2011-11-17 76 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()); 
     } 
    }