首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MEF 2中的“缺失依赖”异常

MEF 2中的“缺失依赖”异常
EN

Stack Overflow用户
提问于 2014-09-04 07:50:48
回答 2查看 767关注 0票数 8

我正在学习MEF 2。下面的代码抛出异常:

'System.Composition.Hosting.CompositionFailedException‘类型的未处理异常发生在System.Composition.TypedParts.dll中 附加信息:缺少对“MEFStudy.Program”的依赖关系“MessageSenders”。

调用SatisfyImports()方法时。为什么?

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Hosting;


using System.Reflection;

namespace MEFStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Run();
        }

        [ImportMany]
        private List<IMessageSender> MessageSenders { get; set; }

        public void Run()
        {
            Compose();
            foreach (IMessageSender sender in MessageSenders)
            {
                sender.Send();
            }

        }

        private void Compose()
        {
            CompositionHost host = new ContainerConfiguration().WithAssembly(Assembly.GetExecutingAssembly()).CreateContainer();
            host.SatisfyImports(this);   // <=========== HERE
            host.Dispose();

        }
    }

    public interface IMessageSender
    {
        void Send();
    }

    [Export(typeof(IMessageSender))]
    public class EmailSender1 : IMessageSender
    {
        public void Send()
        {
            Console.WriteLine("EmailSender1");
        }
    }

    [Export(typeof(IMessageSender))]
    public class EmailSender2 : IMessageSender
    {
        public void Send()
        {
            Console.WriteLine("EmailSender2");
        }
    }

}

更新1

根据here的说法,有两个版本的MEF。

  • 使用.NET框架的不可移植的
  • 可在NuGet上使用的便携式

List<IMessageSender>方法适用于不可移植的方法。但不能用便携的。这是个虫子吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-04 08:35:19

我意外地更改了以下代码:

代码语言:javascript
复制
[ImportMany]
private List<IMessageSender> MessageSenders { get; set; }

代码语言:javascript
复制
[ImportMany]
private IEnumerable<IMessageSender> MessageSenders { get; set; }

它解决了这个问题。

但是,为什么?List<T>不是IEnumerable<T>吗?

添加

更奇怪的是,我把IEnumerable改成了IList,它起作用了。为什么?

可能解释

(我想分享我对此的解释。)

下面的接口可以完全复制相同的错误。

代码语言:javascript
复制
interface IMyList<T> : IList<T>
{

}

[System.Composition.ImportMany] // MEF 2
private IMyList<IMessageSender> MessageSenders { get; set; }

下面的MEF 2源说明了原因。

3 SupportedContactTypes的Equals()方法使用IMyList<>返回false。因此,在MEF2中,IMyList<>不会返回有效的导出。MEF 2不允许使用ImportMany属性修饰的属性的默认值。因此,在下面的逻辑中,将引发缺少依赖项的异常。

因此我们可以说,ImportMany属性只支持数组和3种支持的泛型类型。

票数 4
EN

Stack Overflow用户

发布于 2014-09-16 08:25:13

这有点太长了,不能发表评论:

我猜想MEF的目的是用于接口,而不是具体的类。因此,在我看来,列表中缺少的依赖似乎是一种设计选择,MEF只是缺少了它的导出定义。

在您期望使用IMyList的情况下,同样的机制也适用: MEF没有与该接口相关联的具体类型被实例化,因为没有为它定义导出。即使列表满足所有需求,也需要为IMyList显式地导出它。(例如,对于单元测试来说,这很方便,因为您只需要将导出更改为模拟对象。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25660013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档