2011-08-04 21 views
12

Tôi đang sử dụng MEF để tải các plugin trong ứng dụng của mình. Mọi thứ đều hoạt động, nhưng tôi muốn các phần mới được phát hiện khi chúng được thả vào thư mục ứng dụng của tôi. Điều này có thể không? DirectoryCatalog có một sự kiện đã thay đổi nhưng tôi không chắc nó hoạt động như thế nào.Làm thế nào để khám phá các bộ phận MEF mới trong khi ứng dụng đang chạy?

Đây là mã của tôi ngay bây giờ:

public sealed class RevealerFactory 
{ 
    private static readonly Lazy<RevealerFactory> lazy = 
      new Lazy<RevealerFactory>(() => new RevealerFactory()); 

    public static RevealerFactory Instance { get { return lazy.Value; } } 

    private FileSystemWatcher watcher; 

    private RevealerFactory() 
    { 
     Initialize(); 
    } 

    [ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)] 
    private IEnumerable<Lazy<IRevealer, IRevealerCapabilities>> Revealers { 
     get; 
     set; 
    } 

    public IRevealer GetRevealer(Uri uri) 
    { 
     return (from revealer in Revealers 
       where uri.Host.Equals(revealer.Metadata.Host, 
             StringComparison.OrdinalIgnoreCase) 
        && revealer.Value.IsRevelable(uri) 
       select revealer.Value).FirstOrDefault(); 
    } 

    private void Initialize() 
    { 
     var catalog = new DirectoryCatalog(
      Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) 
             + "/SDownloader/Revealers"); 
     var container = new CompositionContainer(catalog); 
     container.ComposeParts(this); 
    } 
} 

Trả lời

21

Bạn có thể sử dụng để phát hiện FileSystemWatcher DLL mới bị rơi trong thư mục plugin của bạn. Sau đó, bạn có thể xử lý các sự kiện đó bằng cách gọi DirectoryCatalog.Refresh hoặc AggregateCatalog.Catalogs.Add để cập nhật bố cục MEF với các phần mới.

Một số điều cần phải nhận thức:

  1. Bạn cần phải đánh dấu nhập khẩu MEF của bạn như được thiết kế để đối phó với recomposition, như được giải thích trong phần lập trình hướng MEF trên Recomposition. Nếu không, MEF sẽ báo lỗi khi bạn cố cập nhật chúng.

  2. FileSystemWatcher tăng sự kiện trên luồng chủ đề hệ thống (trừ khi bạn sử dụng thuộc tính SynchronizingObject). Lưu ý rằng nếu bạn gọi số DirectoryCatalog.Refresh từ một chuỗi khác, bạn phải tạo CompositionContainer với kích hoạt isThreadSafeFlag. Bạn cũng sẽ phải suy nghĩ về độ an toàn của các bộ định vị thuộc tính sẽ được gọi khi thành phần được cập nhật.

  3. Bạn cũng có thể xóa danh mục bằng cách lấy chúng ra khỏi bộ sưu tập AggregateCatalog.Catalogs. Nhưng không có cách nào để dỡ bỏ các hội đồng liên quan (trừ việc dỡ bỏ toàn bộ Appdomain). Điều đó cũng có nghĩa là bạn vẫn không thể xóa hoặc ghi đè lên một assembly trong khi ứng dụng đang chạy.

+3

ngoài ra bạn có thể xem xét bật sao chép bóng để cho phép hoán đổi nóng cụm của bạn – tartakynov

+0

@tartakynov cách bật sao chép bóng? – zionpi

+0

@zionpi xem chủ đề này http://stackoverflow.com/questions/4595304/change-dll-loaded-with-mef – tartakynov

Các vấn đề liên quan