Для ILogger<out TCategoryName> : ILogger { }
, это не будет ссылаться на TCategoryName
, TCategoryName
будет использоваться в качестве строки для указания category name
во время регистрации.
Вы можете проверить исходный код для ILogger
с помощью Ведение журнала .
Вот процесс.
Для ILogger<AController>
, он создается LoggerFactoryExtensions
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: '.')
public Logger(ILoggerFactory factory)
{
if (factory == null)
{
throw new ArgumentNullException(nameof(factory));
}
_logger = factory.CreateLogger(TypeNameHelper.GetTypeDisplayName(typeof(T), includeGenericParameters: false, nestedTypeDelimiter: '.'));
}
И затем он создаст регистратор с именем cateogoryname в качестве параметра
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
в качестве строки.
Для всего процесса он не создает instace для TCategoryName
, поэтому он не получит циклическую ссылку.