當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資源,看看如何通過支持參數來構建自己的實現。
我很困惑。你談論'MyExportFactory',然後你顯示一個名爲'SrviceProviderFactory'的類。您還可以定義一個方法'CreateServiceProvider',但在其他地方您可以調用'CreateMyExport'。在寫問題的時候你有沒有重新命名? – 2010-12-11 18:55:34