2012-05-23 5 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는 "Task1EmailProvider"와 같이 활성화되는 IEmailProvider의 이름을 확인하고 "공급자"를 제거하고 "Config"를 추가하여 사용할 수있는 "Task1EmailConfig"키를 제공 할 수 있습니다 특정 IEmailConfig 개체를 해결합니다.

마찬가지로 ICommand에도 동일한 작업을 수행하십시오. 그것은 IEmailConfig의 이름을 일관되게 지정하는 것에 의존 할 것이지만, 지금하고있는 모든 손 - 배선을 제거 할 것입니다.

+0

IHandlerSelector를 시도하는 것에 대해 궁금해했는데 어떻게 연결해야할지 확신하지 못했습니다. 그러나 당신이 말했듯이, 컨벤션에 기반한 네이밍은 트릭을 할 수 있습니다. –