2012-05-23 20 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,只是不知道该如何挂钩它。但就像你所说的那样,基于惯例的命名就可以解决问题。 –