2012-05-23 21 views
1

我不確定這是否可行,但我仍然會問這個問題。使用IWindsorInstaller進行動態構造函數注入

我有一個場景,我有一些不同的任務在處理過程中發送電子郵件。

發送電子郵件,通過自定義類

public interface IEmailProvider 
{ 
    void SendEmail(some params); 
} 
public class EmailProvider : IEmailProvider 
{ 
    private readonly IEmailConfig _config; 

    public EmailProvider(IEmailConfig config) 
    { 
     _emailConfig = emailConfig; 
    } 

    public void SendEmail(some params) 
    { 
     // send the email using the params 
    } 
} 

做我有使用電子郵件服務提供者,每個提供自己的實現IEmailConfig的一些任務。

public class Task1 : ICommand 
{ 
    public Task1(IEmailProvider emailProvider) 
    {} 
} 

public class Task2 : ICommand 
{ 
    public Task2(IEmailProvider emailProvider) 
    {} 
} 

這是我設置了一個基本的例子

public class TestInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     // Default email provider set up 
     container.Register(Component.For<IEmailProvider>().ImplementedBy<EmailProvider>() 
      .Named("DefaultEmailProvider") 
      .LifeStyle.Transient); 

     // Task 1 email config set up 
     container.Register(Component.For<IEmailConfig>().ImplementedBy<Task1EmailConfig>() 
      .Named("Task1EmailConfig")); 

     // Task 2 email config set up 
     container.Register(Component.For<IEmailConfig>().ImplementedBy<Task2EmailConfig>() 
      .Named("Task2EmailConfig")); 

     // Task 1 set up 
     container.Register(Component.For<ICommand>().ImplementedBy<Task1>() 
      .Named("Task1Command")); 


     // Task 2 set up 
     container.Register(Component.For<ICommand>().ImplementedBy<Task2>() 
      .Named("Task2Command")); 
    } 
} 

有沒有一種方法可以讓我做出決定,因爲每個ICommand的實現正在解決,哪個IEmailConfig的實施進入EmailProvider類的構造函數?

目前我使用ServiceOverride功能爲每個任務註冊一個EmailProvider實例。這意味着對於每個需要發送電子郵件的任務,我都必須幾乎重複設置電子郵件提供程序,並且它是必需的配置。我最後列出了這個...

Component.For<IEmailConfig>() 
    .ImplementedBy<Task1EmailConfig>() 
    .Named("Task1EmailConfig")); 

Component.For<IEmaiProvider>()   
    .ImplementedBy<EmailProvider>) 
    .Named("Task1EmailProvider") 
    .DependsOn(ServiceOverride.ForKey("config").Eq("Task1Config")); 

Component.For<ICommand>() 
    .ImplementedBy<Task1>() 
    .DependsOn(ServiceOverride.ForKey("emailProvider").Eq("Task1EmailProvider"))); 

這將全部重複爲每個任務。

IEmailProvider實現始終是相同的,它只是IEmailConfig傳遞給每個不同任務的更改。我不禁想到,到目前爲止,我必須有一個更好的解決方案。

回答

1

我認爲幾個handler selectors會爲你想要的。一個用於IEmailProvider,一個用於ICommand。 IEmailProvider可以檢查被激活的IEmailProvider的名稱(如「Task1EmailProvider」)並剝離「Provider」並添加「Config」 - 這會給你關鍵字「Task1EmailConfig」,它可以被使用解決特定的IEmailConfig對象。

同樣,爲ICommand做同樣的事情。它將依賴於您一直指定您的IEmailConfig,但它會消除您現在正在執行的所有手動連線。

+0

我確實想知道如何試試IHandlerSelector,只是不知道該如何掛鉤它。但就像你所說的那樣,基於慣例的命名就可以解決問題。 –