简体   繁体   English

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

[英]MEF 'The export is not assignable to type' error

I have just started using MEF and have hit on an early problem. 我刚刚开始使用MEF并且遇到了早期问题。

I have an interface called DataService: 我有一个名为DataService的接口:

namespace DataAccess
{
  interface IDataService
  {
    string Name { get; }
    string Description { get;}

    List<String> GetPeople();
  }
}

There are 2 implementations of this interface, one for SQL Server and one for Oracle. 此接口有2个实现,一个用于SQL Server,另一个用于Oracle。 Below is the Oracle implementation, SQL Server implementation is exactly the same. 下面是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
}
}

The name and description properties are now defunct as I have replaced these with metadata. 名称和描述属性现在已不存在,因为我已将其替换为元数据。 As you can see, they are very simple objects, I wanted to make sure I could get this to work before I started doing the hard work. 正如你所看到的,它们是非常简单的对象,我想确保在我开始努力工作之前能够让它工作。

This is the code I am using to discover the assemblies: 这是我用来发现程序集的代码:

    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());
    }

This is the error that is produced: 这是产生的错误:

The composition produced a single composition error. 该组合物产生单一组成误差。 The root cause is provided below. 根本原因如下。 Review the CompositionException.Errors property for more detailed information. 查看CompositionException.Errors属性以获取更多详细信息。

1) The export 'DataAccess.Oracle (ContractName="DataAccess.IDataService")' is not assignable to type 'DataAccess.IDataService'. 1)导出'DataAccess.Oracle(ContractName =“DataAccess.IDataService”)'不能分配给'DataAccess.IDataService'类型。

Resulting in: Cannot set import 'MEFTest.Form1.services (ContractName="DataAccess.IDataService")' on part 'MEFTest.Form1'. 导致:无法在部分'MEFTest.Form1'上设置导入'MEFTest.Form1.services(ContractName =“DataAccess.IDataService”)'。 Element: MEFTest.Form1.services (ContractName="DataAccess.IDataService") --> MEFTest.Form1 元素:MEFTest.Form1.services(ContractName =“DataAccess.IDataService”) - > MEFTest.Form1

It doesn't seem to make any sense that it can't assign to the interface that it was designed for! 它似乎没有任何意义,它不能分配给它的设计接口!

Once this problem is solved, my next issue is how to pick one and get an instance of it... 一旦这个问题得到解决,我的下一个问题是如何选择一个并得到它的实例......

It looks like two different versions of your contract assembly (the one with DataAccess.IDataService) are getting loaded. 看起来您的合同程序集的两个不同版本(带有DataAccess.IDataService的版本)正在加载。 One is probably from your executable path and the other from your plugin path. 一个可能来自您的可执行路径,另一个来自您的插件路径。 I touch on this issue a bit in my blog post on How to Debug and Diagnose MEF Failures , and the MSDN page on Best Practices for Assembly Loading goes into more detail. 我在关于如何调试和诊断MEF故障的博客文章中稍微讨论了这个问题,并且有关装配加载最佳实践的MSDN页面更详细。

For me this had a very simple fix. 对我来说这有一个非常简单的修复。

Here's a link ! 这是一个链接 that explains the root cause. 这解释了根本原因。

In my case, I locked my Assembly version down, but my file version travels. 在我的情况下,我锁定了我的程序集版本,但我的文件版本旅行。 My nuget package ID matches my assembly file version. 我的nuget包ID与我的程序集文件版本匹配。

Final result is that I can build continuously, create new nugets, and not have this MEF inteface problem. 最终的结果是我可以不断构建,创建新的nugets,并且没有这个MEF接口问题。

I must tell that I had such an error in completely idiotic context. 我必须告诉我在完全愚蠢的背景下有这样的错误。 Accidentally, I misplaced export directive and put it not on class but on a function inside class: 无意中,我错放了导出指令并将其放在类上,而不是放在类中的函数上:

interface MyInterface
{
  void MyFunction();
}

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

Surprisingly, the code compiled very fine without any warnings. 令人惊讶的是,编译的代码非常精细,没有任何警告。 But then I ve spent hours trying to figure out why MEF fails on my silly misprint! 但后来我花了好几个小时试图找出为什么MEF因我的愚蠢错误而失败!

Yet another cause: 还有另一个原因:

Code: 码:

interface IMyService
{
}

[Export(typeof(IMyService))]
class MyService
{
}

Message: 信息:

The export 'IMyService' is not assignable to type 'IMyService'. 导出“IMyService”不能分配给“IMyService”类型。

Cause: 原因:

The MyService class does not implement the IMyService interface. MyService类未实现IMyService接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM