我使用的是最新的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