为该类作为依赖项的接口的每个具体实现组成一个类的实例

时间:2016-06-17 13:58:31

标签: c# .net dependency-injection inversion-of-control mef

不确定如何为这篇文章做出合理的称号。

说我有一个班级

[Export(typeof(IMessageSender))]
public class MessageSender : IMessageSender
{
    private IMessagingInterface _messagingInterface;
    private IEventAggregator _eventAggregator;

    [ImportingConstructor]
    public MessageSender(IMessagingInterface messagingInterface, IEventAggregator eventAggregator)
    {
        _messagingInterface = messagingInterface;
        _eventAggregator = eventAggregator;
    }

    public void SendMessage(string message)
    {
        _messagingInterface.Write(message);
    }

    public InterfaceStatus GetStatus()
    {
        return _messagingInterface.Status;
    }

    ...
    etc. Many methods in this class.
}

我有几个不同的IMessagingInterface,例如

[Export(typeof(IMessagingInterface))]
public SerialPortInterface : IMessagingInterface
{
    ..
}

[Export(typeof(IMessagingInterface))]
public UdpInterface : IMessagingInterface
{
    ..
}
etc

在我的应用程序中,我目前在我的应用程序启动时实例化了这样的不同部分:

eventAggregator = new EventAggregator();
batch.AddExportedValue<IMessageSender>("SerialPortSender", new MessageSender(new SerialPortInterface(), eventAggregator);
batch.AddExportedValue<IMessageSender>("UdpSender", new MessageSender(new UdpInterface (), eventAggregator);
... 
etc for the rest 

然后我可以使用合约名称指定我想在其他地方注入哪一个。

但是,我觉得自己在引导程序中自己编写这个组合并使用new创建实例是错误的和不必要的,但我还没有找到一种方法来做不同的事情。

2 个答案:

答案 0 :(得分:1)

看看这篇文章: Getting all types that implement an interface

然后使用Activator.CreateInstance(...)构建实例(请参阅:https://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

这样的事情应该这样做:

eventAggregator = new EventAggregator();
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => type.IsAssignableFrom(p));

foreach (var t in types)
{
    var instance = (IMyInteface)Activator.CreateInstance(t);
    batch.AddExportedValue<IMessageSender>(t.Name, new MessageSender(instance, eventAggregator);
}

正如Tchi Yuan指出的那样,使用IOC框架也是一种选择,例如:

这些将根据您提供的配置为您处理程序集扫描和实例创建。

答案 1 :(得分:1)

我过去遇到过这个问题,我所做的是我使用Microsoft Unity与MEF结合,然后简单地将你的Unity容器传递给你的MEF扩展/插件构造函数。使用Unity注册和解析命名依赖项是微不足道的。