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

发布于 2024-09-28 01:33:14 字数 2111 浏览 0 评论 0原文

我刚刚开始使用 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") --> MEFTest.Form1

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

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

I have just started using MEF and have hit on an early problem.

I have an interface called 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.
Below is the Oracle implementation, SQL Server implementation is exactly the same.

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.

1) The export 'DataAccess.Oracle (ContractName="DataAccess.IDataService")' is not assignable to type 'DataAccess.IDataService'.

Resulting in: Cannot set import 'MEFTest.Form1.services (ContractName="DataAccess.IDataService")' on part 'MEFTest.Form1'.
Element: 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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

摇划花蜜的午后 2024-10-05 01:33:14

看起来您的合约程序集的两个不同版本(带有 DataAccess.IDataService 的版本)正在加载。一个可能来自您的可执行路径,另一个来自您的插件路径。我在 如何调试和诊断 MEF 故障,以及 Best 上的 MSDN 页面程序集加载实践有更多细节。

It looks like two different versions of your contract assembly (the one with DataAccess.IDataService) are getting loaded. 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.

喜爱皱眉﹌ 2024-10-05 01:33:14

还有另一个原因:

代码:

interface IMyService
{
}

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

消息:

导出“IMyService”无法分配给类型“IMyService”。

原因:

MyService 类未实现 IMyService 接口。

Yet another cause:

Code:

interface IMyService
{
}

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

Message:

The export 'IMyService' is not assignable to type 'IMyService'.

Cause:

The MyService class does not implement the IMyService interface.

天生の放荡 2024-10-05 01:33:14

对我来说,这是一个非常简单的修复。

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

就我而言,我锁定了程序集版本,但我的文件版本可以移动。我的 nuget 包 ID 与我的程序集文件版本匹配。

最终结果是我可以连续构建、创建新的 nuget,并且不会出现 MEF 接口问题。

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.

Final result is that I can build continuously, create new nugets, and not have this MEF inteface problem.

遥远的她 2024-10-05 01:33:14

我必须告诉你,我在完全愚蠢的情况下犯了这样的错误。不小心,我放错了导出指令,并没有将其放在类上,而是放在类内的函数上:

interface MyInterface
{
  void MyFunction();
}

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

令人惊讶的是,代码编译得非常好,没有任何警告。但后来我花了几个小时试图弄清楚为什么 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文