我刚开始使用MEF并且遇到了早期问题。
我有一个名为DataService的接口:
namespace DataAccess
{
interface IDataService
{
string Name { get; }
string Description { get;}
List<String> 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<string> GetPeople()
{
return new List<String>() { "Oracle boo", "Oracle boo1" };
}
#endregion
}
}
名称和描述属性现在已不存在,因为我已将其替换为元数据。正如你所看到的,它们是非常简单的对象,我想确保在我开始努力工作之前能够让它工作。
这是我用来发现程序集的代码:
private static CompositionContainer _container;
private const string ASSEMBLY_PATTERN = "*.dll";
private AggregateCatalog _catalog;
[ImportMany]
IEnumerable<DataAccess.IDataService> 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”) - &gt; MEFTest.Form1
它似乎没有任何意义,它无法分配给它为其设计的接口!
一旦这个问题得到解决,我的下一个问题是如何选择一个并获得它的实例......
答案 0 :(得分:6)
看起来你的合同程序集的两个不同版本(带有DataAccess.IDataService的版本)正在加载。一个可能来自您的可执行路径,另一个来自您的插件路径。我在How to Debug and Diagnose MEF Failures的博客文章中略微探讨了这个问题,Best Practices for Assembly Loading上的MSDN页面详细介绍了这一点。
答案 1 :(得分:0)
对我来说这有一个非常简单的解决方法。
这是a link!这解释了根本原因。
在我的情况下,我锁定了我的程序集版本,但我的文件版本移动了。我的nuget包ID与我的程序集文件版本匹配。
最终结果是我可以持续构建,创建新的nugets,并且没有MEF接口问题。
答案 2 :(得分:0)
我必须告诉我在完全愚蠢的背景下有这样的错误。无意中,我错放了导出指令并将其放在类上,而不是放在类中的函数上:
interface MyInterface
{
void MyFunction();
}
public class MyClass : MyInterface
{
[Export(typeof(MyInterface))]
void MyFunction() { }
}
令人惊讶的是,编译的代码非常精细,没有任何警告。但后来我花了好几个小时试图找出为什么MEF因我的愚蠢错误而失败了!
答案 3 :(得分:0)
另一个原因:
代码:
interface IMyService
{
}
[Export(typeof(IMyService))]
class MyService
{
}
消息:
导出'IMyService'不能分配给'IMyService'类型。
原因:
MyService
类未实现IMyService
接口。