我有一些正在被少数具体类型使用的界面,例如EmailFormatter
,TextMessageFormatter
等。
public interface IFormatter<T>
{
T Format(CompletedItem completedItem);
}
我遇到的问题是我的EmailNotificationService
是我想要注入EmailFormatter
。此服务的构造函数签名为public EmailNotificationService(IFormatter<string> emailFormatter)
。
我很确定我之前已经看过这个,但是我如何在Windsor中注册它,以便在构造函数参数名称为EmailFormatter
时注入emailFormatter
?
这是我的温莎注册码。
container.Register(Component.For<IFormatter<string>>().ImplementedBy<EmailFormatter>());
答案 0 :(得分:9)
请勿尝试在DI配置中解决此问题。相反,在应用程序的设计中解决它。在我看来,你已经使用相同的界面定义了几个不同的东西。你的要求很明显,因为你说:
我想注入EmailFormatter
你不想注入格式化程序;你想注入一个电子邮件格式化程序。换句话说,您违反了Liskov Substitution Principle。在应用程序中修复此问题。定义IEmailFormatter
界面,让EmailNotificationService
依赖于此:
public interface IEmailFormatter
{
string Format(CompletedItem completedItem);
}
public class EmailNotificationService
{
public EmailNotificationService(IEmailFormatter formatter)
{
}
}
这有两个重要的优点:
EmailNotificationService
确实存在。答案 1 :(得分:6)
服务代码:
public EmailNotificationService(IFormatter<string> emailFormatter){...}
依赖注册码:
container.Register(
Component.For<IFormatter<string>().ImplementedBy<TextMessageFormatter>().Named("TextMessageFormatter"),
Component.For<IFormatter<string>().ImplementedBy<EmailFormatter>().Named("EmailFormatter"),
Component.For<INotificationService>().ImplementedBy<EmailNotificationService>().ServiceOverrrides(
ServiceOverride.ForKey("emailFormatter").Eq("EmailFormatter"))
);