Serilog DI в ASP. NET Ядро, какой интерфейс ILogger вводить? - PullRequest
1 голос
/ 24 апреля 2020

Контекст

Я успешно настроил Serilog в моем ASP. NET Базовом приложении, остается только часть DI.

Вопрос

Теперь у меня есть два интерфейса ILogger, один - Serilog.ILogger, другой - Microsoft.Extensions.Logging.ILogger. Оба работают на основе моего конфига Serilog, и я не знаю, какой использовать? (Я имею в виду, что после конфига Serilog Microsoft.Extensions.Logging.ILogger также корректно регистрируется через Serilog, так что мой конфигурн будет удостоен чести)

В случае Microsoft.Extensions.Logging.ILogger я знаю, как настроить DI, чтобы он работал. Однако в случае Serilog.ILogger я вижу, что у Serilog есть экземпляр stati c Log.Logger (вероятно, синглтон)

Я не хочу использовать это свойство stati c в моем коде, главным образом для причины тестирования, поэтому я хотел бы, чтобы конструктор внедрил его. Решение будет следующим:

services.AddSingleton(Log.Logger); // Log.Logger is a singleton anyway

.. но я беспокоюсь об этом синглтоне в веб-приложении, когда несколько потоков будут одновременно использовать один и тот же экземпляр. Это потокобезопасно? Если это не так, то каким было бы решение использовать Serilog.ILogger с DI?

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Выбор интерфейса для использования в вашем приложении - дело вкуса. Если вы предпочитаете более короткие имена методов Serilog ILogger (например, log.Error против log.LogError), go с этим, в противном случае используйте шаблон Microsoft c ILogger<>. У вас есть контроль над всеми зависимостями, которые вы используете в своих собственных проектах, поэтому нет веских технических причин для предпочтения одной над другой.

Возможно, вам будет интересно прочитать эту проблему в репозитории Serilog:

Должен ли я использовать Microsoft.Extensions.Logging.ILogger или Serilog.ILogger? .

Я лично использую ILogger Serilog во всех своих проектах не только потому, что я Я предпочитаю более короткие имена методов, но также потому, что я предпочитаю , а не , чтобы вводить регистратор в каждый отдельный конструктор каждого класса, и также легко иметь контекстный регистратор для каждого класса , используя Log.ForContext<>, что полезно при устранении неполадок. Например,

public class SomeService
{
    private readonly ILogger _log = Log.ForContext<SomeService>();
    // ...
}

public class SomeRepository
{
    private readonly ILogger _log = Log.ForContext<SomeRepository>();
    // ...
}

Если вы разрабатываете библиотеку , я бы, конечно, рекомендовал использовать generi c ILogger<> от Microsoft вместо зависимости от Serilog и заставляет пользователей вашей библиотеки также принимать зависимость от Serilog.


Log.Logger является поточно-ориентированной, поэтому регистрация в качестве одиночного, как вы делаете выше, правильна, если вы хотите, чтобы все классы совместно использовали один и тот же экземпляр ( без SourceContext s ) - в этом нет ничего плохого.

1 голос
/ 24 апреля 2020

Вы должны настроить вход в файл Program.cs как часть настройки Host, как описано в документации (https://github.com/serilog/serilog/wiki/Getting-Started).

Не следует ничего добавлять вручную на ваш ServiceCollection, как показано выше.

Для DI вы должны ввести дженерик Microsoft c ILogger<>, как описано в документации (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/#create -logs ). Этот экземпляр ILogger<> автоматически регистрирует на всех настроенных вами провайдерах (это может включать Serilog, но также и любые дополнительные настроенные регистраторы, такие как file, console и т. Д. c.).

...