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我必须承认,当我用这种方式搜索
时,我必须认真思考发生了什么。它确实解决了编译问题,我认为这个类的使用方式是解决问题的有效方法。我把它标记为正确答案,即使我的