#c# #logging #dependency-injection #.net-core
#c# #ведение журнала #внедрение зависимости #.net-ядро
Вопрос:
Платформа ведения журнала .Net Core была разработана для использования с внедрением зависимостей. Например, если вы хотите добавить ведение журнала в класс с именем, MyClass
вам нужно добавить ILogger<MyClass>
параметр в конструктор класса:
private readonly ILogger _logger;
MyClass(ILogger<MyClass> logger)
{
_logger = logger;
}
Вопрос
Приведенный выше шаблон кодирования очень распространен (ИМХО), где в качестве резервного поля используется тип ILogger
, а в качестве введенного параметра — тип ILogger<T>
.
Почему бы нам не использовать резервное поле типа ILogger<MyClass>
вместо ILogger
? Есть ли какая-либо разница?
Комментарии:
1. Если вы хотите быть экспертом в чем-то, вам нужно очень хорошо разбираться в основах.
Ответ №1:
ILogger<T>
реализует ILogger
. Вот почему вы можете назначить ILogger<T>
для ILogger
XML-комментария для ILogger<T>
является:
Обычно используется для включения именованного ILogger из внедрения зависимостей.
Это говорит вам о том, что где-то какому-то коду нужен тип для создания регистратора для вас.
Если вы углубитесь в код для service.AddLogging()
, то к ILoggerFactory
добавятся ILogger<>
и IServiceCollection
. ILogger<T>
имеет конкретную реализацию Logger<T>
. Logger<T>
вводит вышеупомянутый ILoggerFactory
параметр, а затем вызывает CreateLogger
передачу displayname типа T. LoggerFactory
затем проверяет кэш уже созданных Logger
файлов на основе T
и возвращает его из кэша, добавляя его, если он не существует.
Таким образом, в принципе, это не добавляет дополнительной функциональности, но внутренне повышает производительность, сохраняя ILogger для каждого типа в кэше и передавая его вам при необходимости. <T>
Необходим, потому что он используется при поиске по словарю / кешу
Ответ №2:
ILogger<T>
определяется следующим образом:
public interface ILogger<out TCategoryName> : ILogger
{
}
Я нашел этот код через «перейти к определению» в Visual Studio, но вы можете увидеть то же самое в теперь заархивированном репозитории здесь.
Исходя из этого, я делаю вывод, что ILogger<T>
предоставляет простой способ задать категорию сгенерированного регистратора, но фактически не изменяет функциональность. Таким образом, я думаю, что использование ILogger
для резервного поля прекрасно, поскольку ILogger<T>
не добавляет никаких методов.
Ответ №3:
Разницы нет. ILogger<T>
Интерфейс не добавляет никаких дополнительных методов или свойств к ILogger
интерфейсу, поэтому вы вольны выбирать то, что вам больше нравится.
Вы можете просмотреть исходный код для каждого из них и код протоколирования ниже: