8

CẬP NHẬTMEF = có thể bị thất vọng?

Như tôi đã cố gắng để có được MEF làm việc suốt ứng dụng của tôi, tôi đang đến qua nhiều một nơi khác, nơi tôi chỉ không hiểu tại sao nó không tự động tạo ra thư viện của tôi khi tôi mong đợi nó . Tôi nghĩ tất cả đều trở lại những gì Reed đang nói về việc cần MEF để tạo ra mọi thứ. Vì vậy, ngay bây giờ, tôi có một lớp đọc XML cần sử dụng CandySettings của tôi, nhưng mặc dù thuộc tính ICandySettings của nó có thuộc tính [Import], nó không được nhập khẩu. Đầu tiên tôi phát hiện ra rằng [Nhập khẩu] không hoạt động trên thống kê, vì vậy tôi đã thay đổi điều này. Nhưng sau đó nó vẫn không hoạt động. Tôi nghĩ đó là vì tôi tự tạo đối tượng đọc XML, và những gì MEF muốn tôi làm thay vào đó là [Nhập] trình đọc XML ... có nghĩa là bây giờ tôi phải có một giao diện cho nó.

Nó gần giống như sử dụng IoC (hoặc cho MEF, ít nhất), đó là một chuyện tất cả hoặc không có gì. Bạn không thể chỉ tự ý sử dụng nó ở đây và ở đó, bởi vì cuối cùng bất cứ lớp nào bạn muốn tiêm các thuộc tính vào cũng cần phải được tạo ra bởi MEF.

Hãy sửa tôi nếu tôi sai!


bài gốc

Vâng, nó không phải là xấu được nêu ra. :) Nhưng tôi có câu hỏi sau khi Reed đã chỉ cho tôi tại MEF như là một thay thế tiềm năng cho IoC (và cho đến nay nó trông khá tốt).

Hãy xem xét các mô hình sau: alt text http://bit.ly/9W0sHt

Như bạn thấy, tôi có một ứng dụng, và ứng dụng này sử dụng Plugins (Rất tiếc, bỏ lỡ hiệp hội đó!). Cả App và Plugins đều yêu cầu sử dụng một đối tượng kiểu CandySettings, được tìm thấy trong một assembly khác.

Lần đầu tiên tôi cố gắng sử dụng phương pháp ComposeParts trong MEF, nhưng cách duy nhất tôi có thể làm việc này là thực hiện điều gì đó như thế này trong mã số plugin.

var container = new CompositionContainer(); 
container.ComposeParts(this, new CandySettings()); 

Nhưng điều này không có ý nghĩa gì, vì tại sao tôi muốn tạo thể hiện của CandySettings trong plugin? Nó sẽ có trong App. Nhưng nếu tôi đặt nó trong mã App, thì Plugin không kỳ diệu tìm ra cách để có được tại ICandySettings, mặc dù tôi đang sử dụng [Import] trong plugin, và [Export] trong CandySettings. EDIT (có lẽ vì tôi nên gọi ComposeParts() từ App và sau đó đi qua nó plugin?)

Con đường tôi đã làm điều đó là sử dụng MEF của DirectoryCatalog, bởi vì điều này cho phép các plugin, khi xây dựng, để quét tất cả các hội đồng trong thư mục hiện tại và tự động nhập mọi thứ được đánh dấu bằng thuộc tính [Nhập]. Vì vậy, nó trông như thế này, và có khả năng trong mỗi plugin:

var catalog = new DirectoryCatalog("."); 
var container = new CompositionContainer(catalog); 
container.ComposeParts(this); 

này hoàn toàn hoạt động tuyệt vời, nhưng tôi không thể không nghĩ rằng đây không phải là cách MEF được dự định sẽ được sử dụng?

+0

Tôi nhớ có một số hạn chế thực sự khi sử dụng MEF và mục đích sử dụng của nó là dành cho các ứng dụng như studio trực quan, v.v. Về cơ bản nói điều này "không phải dành cho tất cả mọi người". http://codebetter.com/blogs/glenn.block/archive/2009/08/16/should-i-use-mef-for-my-general-ioc-needs.aspx –

+0

Tôi nghĩ nó sẽ hoạt động tốt , nhưng đây là một trong những điều tôi đã mong đợi từ khi trở thành một lập trình viên .NET. Có rất nhiều cách để nuôi một con mèo, và về cơ bản cách duy nhất mà bạn sẽ tìm ra là thử một vài lựa chọn. Cho đến nay, tôi đã thực hiện mã của tôi trong MEF và Unity, và cả hai sẽ làm việc, mặc dù tôi vẫn không tích cực rằng cách tôi đã thực hiện nó trong một trong hai khuôn khổ là chính xác 100%. – Dave

+0

Bạn có thể thêm thông báo lỗi bạn nhận được từ 'ComposeParts', mã bạn đang sử dụng để khởi tạo vùng chứa của mình và mã bạn đang sử dụng để xuất/nhập không? –

Trả lời

8

"Bí quyết" ở đây là bạn muốn có MEF tạo các plugin cho bạn.

Cách bạn sẽ làm được điều này là phải có ứng dụng bạn soạn bản thân, với các loại Plugin quy định:

class PluginRepository 
{ 
    [ImportMany(typeof(IPlugin))] 
    IEnumerable<IPlugin> Plugins { get; set; } 
} 

Nếu bạn làm điều này, và có MEF Soạn lớp "kho" của bạn, MEF sẽ xây dựng các đối tượng. Sau đó nó sẽ tự động Soạn chúng khi nó xây dựng chúng, vì vậy ICandySettings sẽ được sáng tác mà không cần bất kỳ sự can thiệp nào cho bạn.

Bạn chỉ cần tự "soạn" một đối tượng nếu MEF không xây dựng nó cho bạn.

+0

Ok, tôi sẽ cố gắng, cảm ơn! Nếu điều đó làm việc trong ứng dụng thử nghiệm, thì kết quả cuối cùng có khả năng trong ứng dụng thực là thay thế trình tải plugin của tôi (trình hiện đang sử dụng Phản chiếu) bằng mã như của bạn, phải không? – Dave

+0

@Dave: Yep. Bạn thực sự không cần phải sử dụng sự phản chiếu chút nào. MEF làm cho điều này cực kỳ đơn giản, rất đáng tin cậy và rất ngắn trên mã ... –

+0

@Reed: Ok, vì vậy tôi đã có giao diện plugin [Nhập] ứng dụng của mình. Ứng dụng của tôi cũng sử dụng DirectoryCatalog để tìm tất cả các mục nhập của assembly. My Plugin [Import] của ICandySettings, và thư viện CandySettings của tôi xuất khẩu thông qua thuộc tính [Export (typeof (ICandySettings))]. Tôi bước qua mã, và trong ứng dụng, tôi xác nhận rằng đối tượng CandySettings và đối tượng Plugin được khởi tạo. Nhưng nhà xây dựng của Plugin cần CandySettings, và tại thời điểm xây dựng CandySettings không được giải quyết ... đây có phải là một hạn chế hay bạn nghĩ rằng tôi có dây sai? Tôi nhận được một ngoại lệ null. – Dave

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