Generics 依赖注入、继承和泛型
我正在使用依赖注入,遇到了一些我无法理解的问题。我有一个需要通用记录器的基类:Generics 依赖注入、继承和泛型,generics,inheritance,dependency-injection,Generics,Inheritance,Dependency Injection,我正在使用依赖注入,遇到了一些我无法理解的问题。我有一个需要通用记录器的基类: public class BaseClass { public BaseClass(ILogger<BaseClass> logger) { // code here } } public class SubClass : BaseClass { public SubClass(ILogger<SubClass> logger) {
public class BaseClass
{
public BaseClass(ILogger<BaseClass> logger)
{
// code here
}
}
public class SubClass : BaseClass
{
public SubClass(ILogger<SubClass> logger)
{
// code here
}
}
公共类基类
{
公共基类(ILogger记录器)
{
//代码在这里
}
}
然后我有一个类继承,它也需要通用记录器:
public class BaseClass
{
public BaseClass(ILogger<BaseClass> logger)
{
// code here
}
}
public class SubClass : BaseClass
{
public SubClass(ILogger<SubClass> logger)
{
// code here
}
}
公共类子类:基类
{
公共子类(ILogger记录器)
{
//代码在这里
}
}
问题是,它不能与消息一起编译;基类不包含接受0个参数的构造函数
如果我能做到这一点,这将很容易解决:
public SubClass(ILogger<SubClass> logger) : base(logger)
public子类(ILogger记录器):基(记录器)
问题是,这也不合法,因为ILogger
不是ILogger
的实例(它的编译没有使用最佳重载匹配,因为…有一些无效参数)
一种可能的解决方案:
我想我不必使用构造函数注入,而是使用dependencysolver
问题:以前肯定有人碰到过这个问题吗?可以使用构造函数注入吗?如果是,我该怎么办
注意:在当前项目中,我使用的是
StructureMap
(),但我认为这里的工具有点不相关。发生这种情况是因为ILogger
不是ILogger
的子类,所以编译器认为您编写了一个新的构造函数。如果您编写
public class SubClass : BaseClass
{
public SubClass(ILogger<SubClass> logger)
: base() // since base class does not have a constructor
// with no arguments, you will get the error
{
// code here
}
}
公共类子类:基类
{
公共子类(ILogger记录器)
:base()//因为基类没有构造函数
//如果没有参数,您将得到错误
{
//代码在这里
}
}
所以你的问题并不是关于依赖注入。这更多的是关于您的体系结构。发生这种情况是因为
ILogger
不是ILogger
的子类,所以编译器认为您编写了一个新的构造函数。如果您编写
public class SubClass : BaseClass
{
public SubClass(ILogger<SubClass> logger)
: base() // since base class does not have a constructor
// with no arguments, you will get the error
{
// code here
}
}
公共类子类:基类
{
公共子类(ILogger记录器)
:base()//因为基类没有构造函数
//如果没有参数,您将得到错误
{
//代码在这里
}
}
所以你的问题并不是关于依赖注入。更多关于您的体系结构。能否将记录器界面更改为:
interface ILogger<out T> where T : BaseClass
接口ILogger,其中T:BaseClass
能否将记录器界面更改为:
interface ILogger<out T> where T : BaseClass
接口ILogger,其中T:BaseClass
您可以在基类中添加一个无参数构造函数,该构造函数将调用参数化构造函数并向其传递一个手动解析的ILogger
实例。大概是这样的:
public BaseClass()
: this(ResolveLogger())
{
}
private static ILogger<BaseClass> ResolveLogger()
{
// resolve the instance manually and return it
}
公共基类()
:此(ResolveLogger())
{
}
专用静态ILogger ResolveLogger()
{
//手动解析实例并返回它
}
这样,如果解析了类型为BaseClass
的实例,它将使用参数化构造函数并注入解析的ILogger
实例。但是,如果解析了派生类,则该派生类将调用无参数的BaseClass()
构造函数和ILogger
将手动解析。您可以在基类中添加一个无参数构造函数,该构造函数将调用参数化构造函数并向其传递一个手动解析的ILogger
实例。大概是这样的:
public BaseClass()
: this(ResolveLogger())
{
}
private static ILogger<BaseClass> ResolveLogger()
{
// resolve the instance manually and return it
}
公共基类()
:此(ResolveLogger())
{
}
专用静态ILogger ResolveLogger()
{
//手动解析实例并返回它
}
这样,如果解析了类型为BaseClass
的实例,它将使用参数化构造函数并注入解析的ILogger
实例。但是,如果解析了派生类,该派生类将调用无参数的BaseClass()
构造函数,并且将手动解析ILogger
。我承认这可能是架构问题(我确实理解错误消息),但是你是说我不能通过构造函数将DI用于这个泛型类(Ilogger
)?DI只是一个工具,可以自动执行手动操作。如果你可以编译你的代码,那么你可以使用DI:)我想你真的需要ILogger
有一个通用参数吗?在太多的项目中使用了ILogger
,所以不能将它改为非通用参数。使用良好(且有用)的是旧的遗留代码。谢谢你的意见!我承认这可能是一个架构问题(我确实理解错误消息),但你是说我不能通过构造函数将DI用于这个泛型类(Ilogger
)?DI只是一个工具,可以自动执行手动操作。如果你可以编译你的代码,那么你可以使用DI:)我想你真的需要ILogger
有一个通用参数吗?在太多的项目中使用了ILogger
,所以不能将它改为非通用参数。使用良好(且有用)的是旧的遗留代码。谢谢你的意见+我必须承认,当我以这种方式用谷歌搜索时,我必须认真思考发生了什么。它确实解决了编译问题,我认为这个类的使用方式是解决问题的有效方法。我把它标记为正确答案,尽管我的头脑并没有真正意识到使用它的后果。+1我必须承认,当我用这种方式搜索时,我必须认真思考发生了什么。它确实解决了编译问题,我认为这个类的使用方式是解决问题的有效方法。我把它标记为正确答案,即使我的