我在这个页面有一点问题:
http://mef.codeplex.com/wikipage?title=Parts&referringTitle=Guide
我有这个程序:
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System;
public class Program
{
[Import]
public IMessageSender MessageSender { get; set; }
public static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
public void Run()
{
Compose();
MessageSender.Send("Message Sent");
}
private void Compose()
{
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
public interface IMessageSender
{
void Send(string message);
}
[Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
}
我不明白我如何编辑它以使用此代码:
[Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender {
...
}
[Export(typeof(IMessageSender))]
public class TCPSender : IMessageSender {
...
}
public class Notifier {
[ImportMany]
public IEnumerable<IMessageSender> Senders {get; set;}
public void Notify(string message) {
foreach(IMessageSender sender in Senders)
sender.Send(message);
}
}
答案 0 :(得分:2)
我认为你期待的是:
public interface INotifier
{
void Notify(string message);
}
[Export(typeof(INotifier))]
public class Notifier : INotifier
{
[ImportMany]
public IEnumerable<IMessageSender> Senders { get; set; }
public void Notify(string message)
{
foreach (var sender in Senders)
sender.Send(message);
}
}
您可以[Import]
INotifier
的实例:
[Import]
public INotifier Notifier { get; set; }
虽然,我更喜欢构造函数注入,因为它更好地表达了类的依赖关系:
[Export(typeof(INotifier))]
public class Notifier : INotifier
{
private readonly IEnumerable<IMessageSender> _senders;
[ImportingConstructor]
public Notifier(IEnumerable<IMessageSender> senders)
{
_senders = senders;
}
public void Notify(string message)
{
foreach (var sender in _senders)
sender.Send(message);
}
}
答案 1 :(得分:0)
该示例用于解释将接口或抽象类指定为导出类型的可能性,即使这是在第一个示例中完成的操作也是如此。这与导出具体类型不同,例如[Export(typeof(EMailSender))]可能已经完成,因为您的导入类必须只知道契约,而不是类/类的真实名称。此外,它还显示了通过ImportMany属性导入实现接口的所有导出类型的方法。要在代码中使用它,使其保持尽可能简单,即不引入Matthew建议的其他导入级别或构造函数注入(请查看http://mef.codeplex.com/wikipage?title=Declaring%20Imports&referringTitle=Guide),您只需在Program类中修改这些方法:
public void Run()
{
Notifier nfr = new Notifier();
Compose(nfr);
nfr.Notify("Message Sent");
}
private void Compose(Notifier nfr)
{
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(nfr);
}
这应该在程序集中执行IMessageSender的所有不同实现的Send方法。