Dependency injection 使用IWindsorInstaller的动态构造函数注入
我不确定这是否可行,但我想我还是会问这个问题 我有一个场景,我有许多不同的任务,在处理过程中发送电子邮件 通过自定义类发送电子邮件Dependency injection 使用IWindsorInstaller的动态构造函数注入,dependency-injection,castle-windsor,castle,Dependency Injection,Castle Windsor,Castle,我不确定这是否可行,但我想我还是会问这个问题 我有一个场景,我有许多不同的任务,在处理过程中发送电子邮件 通过自定义类发送电子邮件 public interface IEmailProvider { void SendEmail(some params); } public class EmailProvider : IEmailProvider { private readonly IEmailConfig _config; public EmailProvider(
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"));
}
}
公共类测试安装程序:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{
//默认电子邮件提供程序设置
container.Register(Component.For().ImplementedBy()实现)
.命名(“DefaultEmailProvider”)
(生活方式,短暂),;
//任务1电子邮件配置设置
container.Register(Component.For().ImplementedBy()实现)
。命名为(“Task1EmailConfig”);
//任务2电子邮件配置设置
container.Register(Component.For().ImplementedBy()实现)
。命名为(“Task2EmailConfig”);
//任务1设置
container.Register(Component.For().ImplementedBy()实现)
。命名为(“任务1司令部”);
//任务2设置
container.Register(Component.For().ImplementedBy()实现)
。命名为(“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")));
Component.For()
.由()实施
。命名为(“Task1EmailConfig”);
用于()的组件
。实施人)
.Named(“Task1EmailProvider”)
.DependsOn(ServiceOverride.ForKey(“配置”).Eq(“任务1配置”));
用于()的组件
.由()实施
.DependsOn(ServiceOverride.ForKey(“emailProvider”).Eq(“Task1EmailProvider”));
每个任务都将复制这些内容
IEmailProvider实现始终是相同的,只有传入的IEmailConfig会针对每个不同的任务进行更改。我忍不住想,对于目前为止我所得到的解决方案,一定有一个更简洁的解决方案。我想有两个解决方案可以满足你的需要。一个用于IEmailProvider,一个用于ICommand
IEmailProvider one可以检查正在激活的IEmailProvider的名称(如“Task1EmailProvider”),然后去掉“Provider”并添加“Config”——这将为您提供键“Task1EmailConfig”,可用于解析特定的IEmailConfig对象
同样,对ICommand的也要做同样的事情。它将依赖于您对IEmailConfig的命名的一致性,但它将消除您现在正在进行的所有手动布线。我认为有两种方法可以满足您的需要。一个用于IEmailProvider,一个用于ICommand
IEmailProvider one可以检查正在激活的IEmailProvider的名称(如“Task1EmailProvider”),然后去掉“Provider”并添加“Config”——这将为您提供键“Task1EmailConfig”,可用于解析特定的IEmailConfig对象
同样,对ICommand的也要做同样的事情。它将依赖于您对IEmailConfig的统一命名,但它将消除您现在正在进行的所有手动连接。我确实想尝试IHandlerSelector,只是不确定如何连接它。但正如您所说,基于约定的命名可能会起作用。我确实想尝试IHandlerSelector,只是不确定如何连接它。但正如您所说,基于约定的命名可能会起作用。