我正在学习MEF 2。下面的代码抛出异常:
'System.Composition.Hosting.CompositionFailedException‘类型的未处理异常发生在System.Composition.TypedParts.dll中 附加信息:缺少对“MEFStudy.Program”的依赖关系“MessageSenders”。
调用SatisfyImports()方法时。为什么?
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。
List<IMessageSender>方法适用于不可移植的方法。但不能用便携的。这是个虫子吗?
发布于 2014-09-04 08:35:19
我意外地更改了以下代码:
[ImportMany]
private List<IMessageSender> MessageSenders { get; set; }至
[ImportMany]
private IEnumerable<IMessageSender> MessageSenders { get; set; }它解决了这个问题。
但是,为什么?List<T>不是IEnumerable<T>吗?
添加
更奇怪的是,我把IEnumerable改成了IList,它起作用了。为什么?
可能解释
(我想分享我对此的解释。)
下面的接口可以完全复制相同的错误。
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种支持的泛型类型。
发布于 2014-09-16 08:25:13
这有点太长了,不能发表评论:
我猜想MEF的目的是用于接口,而不是具体的类。因此,在我看来,列表中缺少的依赖似乎是一种设计选择,MEF只是缺少了它的导出定义。
在您期望使用IMyList的情况下,同样的机制也适用: MEF没有与该接口相关联的具体类型被实例化,因为没有为它定义导出。即使列表满足所有需求,也需要为IMyList显式地导出它。(例如,对于单元测试来说,这很方便,因为您只需要将导出更改为模拟对象。)
https://stackoverflow.com/questions/25660013
复制相似问题