我正在尝试使用Unity Configuration向类属性添加依赖项,而且我尝试注入的类型也是通用的。
我有界面
public interface ISendMessage
{
void Send(string contact, string message);
}
类
public class EmailService : ISendMessage
{
public void Send(string contact, string message)
{
// do
}
}
类
public class MessageService<T> where T : ISendMessage
{
}
我尝试在其他类
中通过构造函数注入使用它public MyService(MessageService<ISendMessage> messageService)
{
}
我如何注入MessageService<EmailService>
代替MessageService<ISendMessage>
?
我尝试通过app.config
来做<alias alias="MessageService'1" type="MyNamespace.MessageService'1, MyAssembly" />
<alias alias="EmailMessageService'1" type="MyNamespace.MessageService'1[[MyNamespace.EmailService, MyAssembly]], MyAssembly" />
我收到错误
无法解析类型名称或别名MessageService'1。请 检查配置文件并验证此类型名称。
我如何传递MessageService<T>
实现参数MessageService<EmailService>
?
由于
更新
我将课程修改为以下内容:
public class MessageService<T> where T : ISendMessage
{
private T service;
[Dependency]
public T Service
{
get { return service; }
set { service = value; }
}
}
并使用配置
<alias alias="ISendMessage" type="MyNamespace.ISendMessage, MyAssembly" />
<alias alias="EmailService" type="MyNamespace.EmailService, MyAssembly" />
<register type="ISendMessage" mapTo="EmailService">
</register>
它有效: - )
答案 0 :(得分:6)
您不能简单地将MessageService<ISendMessage>
投射到MessageService<EmailService>
。为此,您需要MessageService<T>
变体。仅支持接口(和委托)的差异。这不是Unity的事情,这是.NET框架的“限制”(以及自4.0以来的C#支持)。所以你需要实现以下接口:
// note the 'out' keyword!!
public interface IMessageService<out T>
where T : ISendMessage
{
T GetSendMessage();
}
MessageService<T>
类必须实现此接口。但即使使用此代码,Unity也不会自动注入此代码。您必须在两种类型之间进行映射。例如,这是一个可能的注册:
container.Register<MessageService<ISendMessage>>(
new InjectionFactory(c =>
c.Resolve<MessageService<EmailService>>()));
请注意,我使用基于代码的配置。尽可能地防止使用基于XML的配置,因为XML配置很脆弱,容易出错,功能不强,难以维护。只能在部署期间或之后注册实际需要的类型(就个人而言,即使这样我也不会使用DI容器的XML API)。