2011-11-17 88 views
0

说我有协议处理程序列表的字典列表,并在客户端服务知道使用基于一个枚举值的协议,这将是不错的选择的协议从传递的I/F的列表在structuremap注入的接口

我怎样才能在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"); 
} 

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

回答

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()); 
     } 
    }