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

时间:2010-10-17 21:27:38

标签: c# mef

我刚开始使用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

它似乎没有任何意义,它无法分配给它为其设计的接口!

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

4 个答案:

答案 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接口。