【发布时间】:2017-07-10 22:00:36
【问题描述】:
我无法让泛型和 DI 在 MVC Core 项目中协同工作。我有一个通用类(这只是一个片段)。我需要初始化 Input 和 Output,因为它们在代码的其他部分中是如何使用的,所以我使用 Activator 来提供初始值和 new() 约束。
public class Message<TIn, TOut> :
where TIn : class, IMessagePart, new()
where TOut : class, IMessagePart, new() {
public Message(){}
public Message(TIn inpart, TOut outpart) {
Input = inpart;
Output = outpart;
}
public TIn Input { get; set; } = (TIn)Activator.CreateInstance(typeof(TIn));
public TOut Output { get; set; } = (TOut)Activator.CreateInstance(typeof(TOut));
}
我还有其他使用的类,它们有一些静态实用程序类。我正在尝试使用 DI 替换这些静态类。
public class Project : IMessagePart{
int y = 1;
var x = StaticUtilityClass.StaticMethod(y);
}
这样使用
var projectMessage = new Message<Project, Project>();
我正在将静态实用程序类转换为实例类并注入它们。我正在使用内置的 .Net 核心容器。我将实用程序转换为实例类,并将它们注册为容器中的具体单例。对于大多数事情,我可以做正常的-
public class SomeClass{
private readonly UtilityClass _utility;
public SomeClass(UtilityClass utility){
_utility = utility;
var x = _utility.Method(1);
}
在我使用泛型之前一切正常。我不能在 projectMessage 上进行构造函数注入,因为泛型需要对其进行 new 并且它具有 new() 约束,所以我需要一个无参数的构造函数。如果我只添加一个注入构造函数,我会得到
'Project' 必须是具有公共无参数的非抽象类型 构造函数,以便将其用作泛型类型中的参数“TIn” 或方法“消息”。
如果我添加两个构造函数,Activator 只会调用不带参数的构造函数,因此不会调用 DI。我尝试了几种不同的方式使用 CreateInstance 的重载,但没有成功。
这里有什么建议吗?我不知道我是否应该继续使用静态,尝试某种服务定位器方法,或者是否有不同的方法来编写泛型。
【问题讨论】:
-
消息对我来说似乎是运行时数据。您不应该使用 DI 容器来构造运行时数据,并且 should not 将运行时数据注入到您的组件中。您为什么要尝试使用 DI 容器来完成此任务?
-
是的,消息是运行时的。它携带对象对到视图。问题的根源在于消息是运行时的并且不使用 DI,但是内部的类(例如 Project)具有对注入有意义的依赖项——比如数据访问。它们是 ModelBound(因此是 Activator)并且需要 noparam。消息不是 DI 层次结构的一部分,服务对内部对象不可用。在某些方面,DI 使参数化构造函数看起来“未参数化”——没有错误。在更一般的意义上,我试图“跳过” DI 层次结构中的一个节点 - 在它上面使用 DI,在它下面使用 DI,但它没有。
标签: c# asp.net-mvc generics dependency-injection