2013-04-22 30 views
10

Cập Nhật Plugin MEF Runtime Số phát hành

Số phát hành

Mã MEF của tôi không cập nhật thích hợp các hội đồng trong thời gian chạy, từ một thư mục liên quan đến một DirectoryCatalog. Các plugin tải tại thời gian chạy succesffully, nhưng khi tôi cập nhật dll và gọi Refresh trên DirectoryCatalog, các assembly không được cập nhật.

Bối cảnh

Tôi đang xây dựng một dll có vùng chứa MEF và sử dụng DirectoryCatalog để tìm thư mục plugin cục bộ. Tôi gọi dll này hiện nay từ một WinForm đơn giản, đó là thiết lập với một dự án riêng biệt để sử dụng ShadowCopy vì vậy tôi có thể ghi đè lên các dlls trong thư mục plugin của tôi. Thay vì sử dụng một FileWatcher để cập nhật thư mục này, tôi đang trưng ra một phương thức công khai gọi refresh trên DirectoryCatalog, vì vậy tôi có thể cập nhật các assembly theo ý muốn thay vì tự động.

lớp cơ sở instantiates catalog và container MEF, và lưu lại dưới dạng các biến lớp để truy cập tham chiếu sau

public class FieldProcessor 
{ 
    private CompositionContainer _container; 
    private DirectoryCatalog dirCatalog; 

    public FieldProcessor() 
    { 
     var catalog = new AggregateCatalog(); 
     //Adds all the parts found in the same assembly as the TestPlugin class 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(TestPlugin).Assembly)); 
     dirCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "Plugin\\"); 
     catalog.Catalogs.Add(dirCatalog); 

     //Create the CompositionContainer with the parts in the catalog 
     _container = new CompositionContainer(catalog); 
    } 

    public void refreshCatalog() 
    { 
     dirCatalog.Refresh(); 
    } 

} ... 

đây là plugin tôi đang cố gắng để ghi đè lên. Thử nghiệm cập nhật của tôi, là các đoạn mã được trả về là đầu ra cho một hộp văn bản, tôi thay đổi Strings mà plugin đang trả về, xây dựng lại và sao chép nó vào thư mục plugin. Nhưng nó không cập nhật cho các ứng dụng đang chạy, cho đến khi tôi đóng và khởi động lại ứng dụng.

[Export(typeof(IPlugin))] 
[ExportMetadata("PluginName", "TestPlugin2")] 
public class TestPlugin2 : IPlugin 
{ 
    public IEnumerable<IField> GetFields(ContextObject contextObject, params string[] parameters) 
    { 
     List<IField> retList = new List<IField>(); 
     //Do Work Return Wrok Results 
     retList.Add(new Field("plugin.TestPlugin2", "TestPluginReturnValue2")); 
     return retList; 
    } 
} 

Sửa

Nhập Tuyên Bố

[ImportMany(AllowRecomposition=true)] 
    IEnumerable<Lazy<IPlugin, IPluginData>> plugins; 

Nghiên cứu

tôi đã thực hiện nghiên cứu khá sâu rộng và ở khắp mọi nơi trong các bài báo và các mẫu mã câu trả lời dường như là, để thêm một DirectoryCatalog để một container và tiết kiệm một tham chiếu của catalog đó, sau đó gọi Refresh trên tham chiếu đó, sau khi một plugin mới được thêm vào, và nó sẽ cập nhật các assembly ... mà tôi đang làm, nhưng nó không hiển thị đầu ra được cập nhật, từ dll plugin mới.

Yêu cầu

Có ai nhìn thấy vấn đề này hoặc biết điều gì có thể gây ra sự cố với hội đồng không cập nhật trong thời gian chạy không? Mọi thông tin hoặc thông tin chi tiết bổ sung sẽ được đánh giá cao.

Độ phân giải

Nhờ Panos và Stumpy cho các liên kết dẫn tôi đến giải pháp vấn đề của tôi. Đối với những người tìm kiếm tri thức trong tương lai, vấn đề chính của tôi là phương thức Refresh không cập nhật các assembly, khi assembly mới có cùng tên assembly giống như dll ghi đè. Đối với POC của tôi, tôi chỉ thử nghiệm xây dựng lại với một ngày gắn vào tên lắp ráp và mọi thứ khác giống nhau, và nó hoạt động như một sự quyến rũ. liên kết của họ trong các nhận xét dưới đây, rất hữu ích và được khuyến nghị nếu bạn có cùng một vấn đề.

+1

DirectoryCatalog.Refresh sẽ không phát hiện assebmlies được cập nhật. Chỉ những người mới hoặc bị xóa. Có một cái nhìn tại câu trả lời này cho một workaround và gợi ý: http://stackoverflow.com/a/14842417/850119 –

+0

dlls của tôi bị khóa xuống khi chúng được nạp vì vậy tôi không thể ghi đè lên chúng với dlls mới. Bạn không có vấn đề này? bạn đã làm điều gì đó khiến họ có thể cập nhật được hay không. –

+0

vâng, tôi đã có vấn đề này. Một trong những bước tôi đã đề cập trong qua là, cho phép "Shadow Copy". Shadow Copy cho phép một chương trình kéo bản sao cục bộ của các hội đồng dll, và thêm chúng vào một bộ đệm cục bộ, thay vì khóa các dll. Điều này đã được kích hoạt để cho phép bạn "dồn nóng" dll trong thời gian chạy, nếu không bạn cần phải dừng chương trình, thay đổi dlls, và sau đó khởi động lại nó. Tôi nghĩ rằng đây là ví dụ tôi nhìn vào, nhưng nếu nó không làm việc cho bạn google MEF và Shadow Copy, http://stackoverflow.com/questions/12593308/mef-and-shadowcopying-dlls-so-that-i -can-overwrite-them-at-runtime – Madullah

Trả lời

3

bạn có đặt tham số AllowRecomposition cho thuộc tính Nhập của bạn không?

AllowRecomposition 
Gets or sets a value that indicates whether the property or field will be recomposed when exports with a matching contract have changed in the container. 

http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=vs.95).aspx

chỉnh sửa:

DirectoryCatalog không cập nhật lắp ráp, chỉ bổ sung hoặc loại bỏ: http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.refresh.aspx

cho một công trình xung quanh: https://stackoverflow.com/a/14842417/2215320

+0

Tôi đã làm, xin lỗi tôi đã không đăng mã lệnh nhập khẩu ban đầu, tôi đã cập nhật câu hỏi để phản ánh tuyên bố nhập của tôi. – Madullah

+0

và mã làm mới của bạn? Tôi nghĩ vấn đề là bên trong. Bạn nói không sử dụng FileSystemWatcher, làm thế nào để bạn phát hiện và tải lại các hội đồng của bạn? – Niels

+0

Tôi đang hiển thị nó thông qua phương thức RefreshCatalog đã thấy ở trên. Tôi gọi phương thức đó từ một sự kiện nhấn nút trên một winForm. – Madullah

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