2008-09-03 120 views
21

有沒有人與微軟的Managed Extensibility Framework(MEF)合作過?有點聽起來它試圖成爲所有人的所有東西 - 這是一個插件管理器!這是鴨子打字!我想知道,如果有人有經驗,積極或消極。.NET的託管擴展框架?

我們目前正在計劃在下一個大項目中使用通用IoC實現ala MvcContrib。我們應該把MEF扔進混合體中嗎?

回答

33

我們不打算讓MEF成爲一個通用的IoC。考慮MEF的IoC方面的最佳方式是實現細節。我們使用IoC作爲模式,因爲它是解決我們正在尋求解決的問題的好方法。

MEF專注於可擴展性。當你想到MEF將它視爲推動我們平臺發展的投資時。我們未來的產品和平臺將利用MEF作爲增加擴展性的標準機制。第三方產品和框架也將能夠利用這種相同的機制。 MEF的平均「用戶」將編寫MEF將消耗的組件,並且不會直接在其應用程序中使用MEF。

想象一下,當您希望將來擴展我們的平臺時,您將一個dll放入bin文件夾中即可完成。啓用了MEF的應用程序隨着新的擴展程序亮起。這是MEF的願景。

1

這不是注射控制容器。它是插件支持框架。

1

我想說它會掛在.NET 4.0框架中的'系統'命名空間,你不能犯太多錯誤。看看MEF如何演變以及Hamilton Verissimo(Castle)對MEF的方向有何影響將會很有趣。

如果它叫起來像鴨子,那麼它也許會是IoC容器的當前羊羣的一部分...

8

這個職位是指託管擴展框架預覽2.

所以,我通過了MEF並寫下了一個快速的「Hello World」,下面將會介紹它。我必須說,深入並理解它非常容易。目錄系統非常好,使得MEF本身非常簡單。把它指向一個插件程序集的目錄並讓它處理剩下的東西是很簡單的。 MEF的遺產ala Prism肯定會透露,但我認爲如果不是這樣,它會很奇怪,因爲這兩個框架都是關於構圖的。

我認爲我最喜歡的東西是_container.Compose()的「魔術」。如果你看看HelloMEF類,你會發現greetings字段永遠不會被任何代碼初始化,這只是感覺很有趣。我認爲我更喜歡IoC容器的工作方式,您明確要求容器爲您構建對象。我想知道是否有某種「Nothing」或「Empty」泛型初始化器可能會按順序排列。即

private IGreetings greetings = CompositionServices.Empty<IGreetings>(); 

即至少填充有「東西」,直到該對象作爲容器組成代碼運行與真正的「什麼」,以填充它。我不知道 - 它記錄了一些我一直不喜歡的Visual Basic的Empty或Nothing關鍵字。如果其他人對此有一些想法,我想聽聽他們。也許這是我需要解決的問題。它被標記爲一個胖胖的[Import]屬性,所以它不像是一個完整的神祕或任何東西。

控制對象的生命週期並不明顯,但默認情況下,除非嚮導出的類添加[CompositionOptions]屬性,否則默認情況下所有東西都是單例。那讓我們指定Factory或Singleton。很高興看到Pooled在某個時候添加到此列表中。

我不太清楚鴨子打字功能的工作原理。它看起來更像是創建對象時的元數據注入,而不是鴨子打字。它看起來像只能添加一個額外的鴨子。但就像我說的,我還不清楚這些功能的工作原理。希望我能回來並在以後填寫。

我認爲這將是一個好主意,以陰影複製由DirectoryPartCatalog加載的DLL。現在,一旦MEF抓住它們,DLL就會被鎖定。這也可以讓你添加一個目錄觀察器並捕獲更新的插件。這將是非常可愛的...

最後,我擔心插件DLL的可信度如何,以及MEF如何在部分信任環境中運行。我懷疑使用MEF的應用程序需要完全信任。在他們自己的AppDomain中加載插件也是明智的做法。我知道它有點System.AddIn,但它會允許非常明確的用戶插件和系統插件之間的分離。

好的 - 足夠的說話。這裏是MEF和C#中的Hello World。請享用!

using System; 
using System.ComponentModel.Composition; 
using System.Reflection; 

namespace HelloMEF 
{ 
    public interface IGreetings 
    { 
     void Hello(); 
    } 

    [Export(typeof(IGreetings))] 
    public class Greetings : IGreetings 
    { 
     public void Hello() 
     { 
      Console.WriteLine("Hello world!"); 
     } 
    } 

    class HelloMEF : IDisposable 
    { 
     private readonly CompositionContainer _container; 

     [Import(typeof(IGreetings))] 
     private IGreetings greetings = null; 

     public HelloMEF() 
     { 
      var catalog = new AggregateCatalog(); 
      catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); 
      _container = new CompositionContainer(catalog); 
      var batch = new CompositionBatch(); 
      batch.AddPart(this); 
      container.Compose(batch); 

     } 

     public void Run() 
     { 
      greetings.Hello(); 
     } 

     public void Dispose() 
     { 
      _container.Dispose(); 
     } 

     static void Main() 
     { 
      using (var helloMef = new HelloMEF()) 
       helloMef.Run(); 
     } 
    } 
} 
+1

我最近與MEF預覽4打球,他們已經有些清理了代碼。 AggregatingComposablePartCatalog現在只是AggregateCatalog等,所有圍繞一個大贏家恕我直言 – 2009-02-18 02:06:29

2

安迪,我相信格倫座回答很多人的(自然)的問題,如這些在這個線程了在MSDN MEF論壇:

Comparison of CompositionContainer with traditional IoC Containers

在某種程度上,Artem上面的回答與MEF背後的主要意圖是正確的,這是可擴展性而不是組成性。如果您主要對構圖感興趣,那麼請使用其他常見的IoC嫌疑犯之一。另一方面,如果您主要關心可擴展性,那麼引入目錄,部件,元數據標籤,鴨子打字和延遲加載都會產生一些有趣的可能性。另外,Krzysztof Cwalina在解釋MEF和System.Addins如何相互關聯時拍攝了here

4

關於Andy對MEF加載擴展的安全性問題(抱歉,我還沒有足夠的積分:)),解決此問題的地方在目錄中。 MEF目錄完全可插入,因此您可以在加載之前編寫一個自定義目錄來驗證程序集密鑰等。如果您願意,您甚至可以使用CAS。我們正在研究可能提供的鉤子,使您無需編寫目錄即可完成此操作。但是,當前目錄的來源可以免費獲取。我懷疑最低限度是某人(可能在我們的團隊中)將執行一個並將其放入CodePlex上的擴展/ contrib項目中。

4

鴨子打字不會在V1中出貨,雖然它在當前的下降。在未來的下降中,我們將用可插入的適配器機制替換它,其中可以掛鉤鴨子打字機制。我們研究duck typing的原因是爲了解決版本控制的情況。通過鴨子打字,您可以刪除出口商和進口商之間的共享參考,從而允許多個版本的合同並排生活。在這個崗位,並在此