structuremap注入接口的字典列表

时间:2011-11-17 16:30:50

标签: dependency-injection structuremap

假设我有一个协议处理程序列表,并且客户端服务根据枚举值知道要使用哪个协议,从传入的i / f列表中选择协议会很好。

如何在StructureMap中实现这一目标?:

   public EmailTransportService(interfaces...,
                               IDictionary<EmailAccountType, IEmailTransportHandler> transportHandlers)

目前,我正在使用ObjectFactory获取命名实例,如下所示:

  _emailTransportHandlers = new Dictionary<EmailAccountType, string>
                                        {
                                            {EmailAccountType.Pop3, "Pop3Handler"},
                                            {EmailAccountType.IMAP, "IMapHandler"}
                                        };

然后像这样解决:

 private IEmailTransportHandler GetTransportHandler(EmailAccountType accountType)
        {            
            return ObjectFactory.GetNamedInstance<IEmailTransportHandler>(_emailTransportHandlers[accountType]);
        }

但我不喜欢这个,因为在我的单元测试中难以验证对处理程序的调用。

我的服务注册表如下所示:

 public EmailTransportServiceRegistry()
 {
            Scan(x =>
                     {
                        ....                      
                     });

            For<IEmailTransportHandler>().Use<ActiveUpPop3Handler>().Named("Pop3Handler");
            For<IEmailTransportHandler>().Use<ActiveUpIMap4Handler>().Named("IMapHandler");
}

所以基本上我依赖于基于协议类型字典列表的命名实例。

1 个答案:

答案 0 :(得分:0)

我的解决方案是从客户端服务中获取静态注册方法,如下所示:

public static IDictionary<EmailAccountType, IEmailTransportHandler> RxHandlerRegistration()
        {
            return new Dictionary<EmailAccountType, IEmailTransportHandler>
                       {                                 
                           // following registrations use ActiveUp library for pop3/imap (http://mailsystem.codeplex.com/)
                           {EmailAccountType.Pop3, ObjectFactory.GetInstance<ActiveUpPop3Handler>()},
                           {EmailAccountType.IMAP, ObjectFactory.GetInstance<ActiveUpIMap4Handler>()}
                       };
        }

然后在ServiceRegistry类中:

 public class EmailTransportServiceRegistry : ServiceRegistry
    {
        public EmailTransportServiceRegistry()
        {    
            // other registries...    
            For<IDictionary<EmailAccountType, IEmailTransportHandler>>().Use(x => EmailTransportService.RxHandlerRegistration());
        }
    }