我使用的是最新的MEF 2預覽版本Codeplex homepage,它應該添加開放式泛型支持。確實如此,但在這種特殊情況下,MEF未能構成通用實現通用接口的:MEF 2無法導入泛型接口的通用實現
public interface IOuter
{
IInner Value { get; }
}
[Export(typeof(IOuter))]
public class MyOuter : IOuter
{
[ImportingConstructor]
public MyOuter(InnerGenericClass<string, int> value)
{
this.Value = value;
}
public IInner Value { get; private set; }
}
public interface IInner
{
void Say();
}
public interface IGenericInner<T, K> : IInner
{
// something else here
}
[Export(typeof(IGenericInner<,>))]
public class InnerGenericClass<T, K> : IGenericInner<T, K>
{
public void Say()
{
Console.WriteLine("{0}, {1}", typeof(T), typeof(K));
}
}
class Startup
{
public void CatalogSetup()
{
var catalog = new AggregateCatalog(
new AssemblyCatalog(Assembly.GetExecutingAssembly())
);
var container = new CompositionContainer(catalog, CompositionOptions.DisableSilentRejection);
var batch = new CompositionBatch();
container.Compose(batch);
var outer = container.GetExportedValue<IOuter>();
outer.Value.Say();
}
}
這裏的CompositionExpection:
The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) No exports were found that match the constraint:
ContractName ConsoleApplication1.InnerGenericClass(System.String,System.Int32)
RequiredTypeIdentity ConsoleApplication1.InnerGenericClass(System.String,System.Int32)
Resulting in: Cannot set import 'ConsoleApplication1.MyOuter.Value (ContractName="ConsoleApplication1.InnerGenericClass(System.String,System.Int32)")' on part 'ConsoleApplication1.MyOuter'.
Element: ConsoleApplication1.MyOuter.Value (ContractName="ConsoleApplication1.InnerGenericClass(System.String,System.Int32)") --> ConsoleApplication1.MyOuter --> AssemblyCatalog (Assembly="ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
Resulting in: Cannot get export 'ConsoleApplication1.MyOuter (ContractName="ConsoleApplication1.IOuter")' from part 'ConsoleApplication1.MyOuter'.
Element: ConsoleApplication1.MyOuter (ContractName="ConsoleApplication1.IOuter") --> ConsoleApplication1.MyOuter --> AssemblyCatalog (Assembly="ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
甚至當我移動進口的
InnerGenericClass
相同的異常被拋出屬性MyOuter.Value:
[Export(typeof(IOuter))]
public class MyOuter : IOuter
{
[Import(typeof(InnerGenericClass<string, int>))]
public IInner Value { get; private set; }
}
是什麼奇怪的,就是,它確實工作,當我改變進口類型IGenericInner:
[Export(typeof(IOuter))]
public class MyOuter : IOuter
{
[ImportingConstructor]
public MyOuter(IGenericInner<string, int> value)
{
this.Value = value;
}
public IInner Value { get; private set; }
}
什麼是更加古怪,是,它不起作用,導入時通過屬性。
摘要:我不能使用通用接口導入對象值財產,因爲可能有IGenericInner接口的多種實現(也是我想導入具體的實現,但是這並不重要)。
我希望在這種情況下我不必繞過MEF。
不幸的是,我只用了4.0(請參閱問題標籤)。預覽版本中您的建議不起作用。我無法升級到4.5,因爲我仍然有運行WinXP的客戶端。 – mnn 2013-02-20 17:48:19
恩,太糟糕了。我'增加了第三個選項。我嘗試避免這種語法,但它解決了這個問題。 – Andreas 2013-02-21 08:46:32
謝謝,但這確實看起來很醜。我想我不會在我的API的這個特定部分使用MEF。 – mnn 2013-02-22 22:57:41