MEF’导出不能分配给’错误’

我刚开始使用MEF并且遇到了早期问题。

我有一个名为DataService的接口:

namespace DataAccess { interface IDataService { string Name { get; } string Description { get;} List GetPeople(); } } 

该接口有2个实现,一个用于SQL Server,另一个用于Oracle。 下面是Oracle实现,SQL Server实现完全一样。

 namespace DataAccess { [Export(typeof(IDataService))] [ExportMetadata("Name","Oracle")] [ExportMetadata("Description","Oracle Data Service")] public class Oracle : IDataService { #region IDataService Members public string Name { get { return "Oracle"; } } public string Description { get { return "Provides data access to Oracle database"; } } public List GetPeople() { return new List() { "Oracle boo", "Oracle boo1" }; } #endregion } } 

名称和描述属性现在已不存在,因为我已将其替换为元数据。 正如你所看到的,它们是非常简单的对象,我想确保在我开始努力工作之前能够让它工作。

这是我用来发现程序集的代码:

  private static CompositionContainer _container; private const string ASSEMBLY_PATTERN = "*.dll"; private AggregateCatalog _catalog; [ImportMany] IEnumerable services { get; set; } private void button3_Click(object sender, EventArgs e) { _catalog = new AggregateCatalog( new DirectoryCatalog(txtLibPath.Text, ASSEMBLY_PATTERN), new AssemblyCatalog(Assembly.GetExecutingAssembly())); _container = new CompositionContainer(_catalog); _container.ComposeParts(this); MessageBox.Show(services.Count().ToString()); } 

这是产生的错误:

该组合物产生单一组成误差。 根本原因如下。 查看CompositionException.Errors属性以获取更多详细信息。

1)导出’DataAccess.Oracle(ContractName =“DataAccess.IDataService”)’不能分配给’DataAccess.IDataService’类型。

导致:无法在部分’MEFTest.Form1’上设置导入’MEFTest.Form1.services(ContractName =“DataAccess.IDataService”)’。 元素:MEFTest.Form1.services(ContractName =“DataAccess.IDataService”) – > MEFTest.Form1

它似乎没有任何意义,它不能分配给它的设计接口!

一旦这个问题得到解决,我的下一个问题是如何选择一个并获得它的实例……

看起来你的合同程序集的两个不同版本(带有DataAccess.IDataService的版本)正在加载。 一个可能来自您的可执行路径,另一个来自您的插件路径。 我在关于如何调试和诊断MEF故障的博客文章中稍微讨论了这个问题,并且有关assembly加载最佳实践的MSDN页面更详细。

对我来说这有一个非常简单的解决方法。

这是一个链接 ! 这解释了根本原因。

在我的情况下,我锁定了我的程序集版本,但我的文件版本旅行。 我的nuget包ID与我的程序集文件版本匹配。

最终结果是我可以不断构建,创建新的nugets,并且没有MEF接口问题。

我必须告诉我,在完全愚蠢的背景下我有这样的错误。 无意中,我放错了导出指令并将其放在类上,而不是放在类中的函数上:

 interface MyInterface { void MyFunction(); } public class MyClass : MyInterface { [Export(typeof(MyInterface))] void MyFunction() { } } 

令人惊讶的是,代码编译得很好,没有任何警告。 但后来我花了好几个小时试图找出为什么MEF因我的愚蠢错误而失败!