2010-12-11 20 views
6

使用MEF的桌面應用程序導入許多'ServiceProviders'。每個部分(ServiceProvider)是一個單獨的DLL內的類。 所有的DLL文件是在使用由桌面應用程序「插件」文件夾中。定製'ExportFactory'

因爲我需要我的部分新實例,ExportFactory是最好的選擇,但問題是我的零件具有構造。我需要傳遞一些參數到構造。這不是由ExportFactory(MEF2,Preview2)支持的部分

的我需要的東西是這樣的:

// Each part has its own dependency 
Dependency dependency = LoadDependency(myPart.Metedata["Name"]); 
// Injecting dependency into part's constructor 
myPart.CreateExport(dependency); 

我不想從我的零件端輸入任何東西

可以找到示例項目(無參數構造函數)here

+0

我很困惑。你談論'MyExportFactory',然後你顯示一個名爲'SrviceProviderFactory'的類。您還可以定義一個方法'CreateServiceProvider',但在其他地方您可以調用'CreateMyExport'。在寫問題的時候你有沒有重新命名? – 2010-12-11 18:55:34

回答

5

當MEF看到類型爲ExportFactory<IFoo>的導入時,它會以特殊方式處理此問題。而不是從字面上看ExportFactory<IFoo>導出,而是看起來代替IFoo導出,並且奇蹟般地爲該類型生成工廠。

你的錯誤是,你期望這個魔法也自動適用於你自己替代ExportFactory,你叫SrviceProviderFactory。這不是真的。當您在某處導入SrviceProviderFactory<IFoo,IFooMetadata>時,MEF會逐字查找該類型的導出。

直接的解決方案是給它這個輸出。爲每個IServiceProvider實現手動導出一個工廠。舉例來說,如果你有一個FooServiceProvider

public class FooServiceProvider : IServiceProvider 
{ 
    public FooServiceProvider(Dependency dependency) 
    { 
     ... 
    } 
} 

然後,你還需要有一個FooServiceProviderFactory:

[Export(typeof(IServiceProviderFactory))] 
[ExportMetaData("foo", "bar")] 
public class FooServiceProviderFactory : IServiceProviderFactory 
{ 
    public IServiceProvider CreateServiceProvider(Dependency d) 
    { 
     return new FooServiceProvider(d); 
    } 
} 

然後你的進口商可以基於元數據選擇合適的工廠:

public class FactoryUser 
{ 
    [ImportMany] 
    public Lazy<IServiceProviderFactory,IDictionary<string,object>>[] Factories 
    { 
     get; 
     set; 
    } 

    public void DoSomething() 
    { 
     var factory = Factories.First(x => x.Metadata["foo"] == "bar").Value; 
     var serviceProvider = factory.CreateServiceProvider(someDependency); 
     ... 
    } 
} 

這裏令人討厭的是,對於每個服務提供者的實現,您還需要創建和導出工廠實現。您可以通過創建通用工廠基類來保存工作(如SrviceProviderFactory),但您仍然必須派生特定的類,因爲您無法在MEF導出中使用泛型類型參數。 更新:我相信.NET 4.5現在支持導出開放的泛型類型。

這就是爲什麼I already suggested you export Func instead,但顯然你不喜歡這個答案。

你也可以嘗試複製ExportFactory魔法。這是可能的,但是MEF的一個非常先進的用例。如果你想這樣做,我建議你看看ExportFactoryProvider的MEF資源,看看如何通過支持參數來構建自己的實現。