首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET核中协方差类型依赖注入的工作原理

.NET核中协方差类型依赖注入的工作原理
EN

Stack Overflow用户
提问于 2019-10-21 11:20:33
回答 1查看 563关注 0票数 0

最近,我在使用ASP.net核心3.0时被卡住了。正如我们所知道的,构造函数如何在.NET核心中为依赖注入工作。

例如:

代码语言:javascript
复制
public class A: IA{
   private readonly IB<B> iB;
   public A(IB<B> iB){
       this.iB = iB;
   }
}

依赖关系的解决方式如下所示。

代码语言:javascript
复制
IB<B> iB = new B();
IA iA = new A(iB);

这很好。我明白,但是“协方差泛型”呢?

例如ILogger<ControllerName>

见下面的代码

代码语言:javascript
复制
public class AController {
   private readonly ILogger<AController> iLogger;
   public AController(ILogger<AController> iLogger){
       this.iLogger = iLogger;
   }
}

因此,在本例中,它看起来像AController正在获得循环引用。如果您寻找ILogger的定义,则如下所示

代码语言:javascript
复制
ILogger<out TCategoryName> : ILogger { }

协方差泛型

EN

回答 1

Stack Overflow用户

发布于 2019-10-22 06:49:32

对于ILogger<out TCategoryName> : ILogger { },它将不引用TCategoryNameTCategoryName将用作字符串来指示日志记录时的category name

您可以通过ILogger通过日志记录检查源代码。

这是一个过程。

对于ILogger<AController>,它是由LoggerFactoryExtensions封装的。

代码语言:javascript
复制
public static ILogger<T> CreateLogger<T>(this ILoggerFactory factory)
{
    if (factory == null)
    {
        throw new ArgumentNullException(nameof(factory));
    }
    return new Logger<T>(factory);
}

对于new Logger<T>(factory);,它将获得带有TypeNameHelper.GetTypeDisplayName(typeof(T), includeGenericParameters: false, nestedTypeDelimiter: '.')的类别名称

代码语言:javascript
复制
public Logger(ILoggerFactory factory)
{
    if (factory == null)
    {
        throw new ArgumentNullException(nameof(factory));
    }

    _logger = factory.CreateLogger(TypeNameHelper.GetTypeDisplayName(typeof(T), includeGenericParameters: false, nestedTypeDelimiter: '.'));
}

然后,它将使用cateogoryname作为参数创建记录器。

代码语言:javascript
复制
    public ILogger CreateLogger(string categoryName)
    {
        if (CheckDisposed())
        {
            throw new ObjectDisposedException(nameof(LoggerFactory));
        }

        lock (_sync)
        {
            if (!_loggers.TryGetValue(categoryName, out var logger))
            {
                logger = new Logger
                {
                    Loggers = CreateLoggers(categoryName),
                };

                (logger.MessageLoggers, logger.ScopeLoggers) = ApplyFilters(logger.Loggers);

                _loggers[categoryName] = logger;
            }

            return logger;
        }
    }

CreateLoggers过程中,它只使用category name作为字符串。

对于整个过程,它不会为TCategoryName创建一个实例,因此不会得到循环引用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58485219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档