Как регистрировать вызовы NLog из библиотеки классов в моем приложении ASP.NET Core MVC? - PullRequest
0 голосов
/ 23 октября 2018

Давайте представим, что у меня есть два проекта.

Первый - это ASP.NET Core MVC проект , для ведения журнала которого используется NLog.Extensions.Logging.Это замечательно;Я могу использовать внедрение зависимостей на моих контроллерах, чтобы получить экземпляр ILogger, а файл nlog.config содержит, ну, в общем, мою конфигурацию NLog.

Второй - это библиотека классов, от которой зависит API,это напрямую зависит от NLog для его регистрации.Он содержит такие вызовы:

public class SampleClass
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

    public void DoStuff()
    {
        if (_failed) Logger.Error("oh no");
    }
}

Эти классы создаются с помощью некоторого рефлексивного волшебства, и я не могу использовать внедрение зависимостей для замены их регистратора.Вы также можете думать о них как о некой модели, которая не может быть реализована при запуске.


Как мне сделать так, чтобы журналы моей библиотеки отображались в выходных данных журналирования API? Я бы ожидал, что они будут пойманы nlog.config автоматически, но они, похоже, не будут.

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Библиотеки классов никогда не должны зависеть от конкретной реализации ведения журнала.Вместо этого вы должны использовать абстракцию, называемую фасад .Библиотека Microsoft.Extensions.Logging - это один из таких фасадов, который вы можете использовать, но есть и другие, такие как Common.Logging.Независимо от того, классы, которые должны использовать ведение журнала, должны быть внедрены с этим абстрактным фасадом ведения журнала.Например:

public class SampleClass
{
    private readonly ILogger _logger;

    public SampleClass(ILogger<SampleClass> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public void DoStuff()
    {
        if (_failed) _logger.LogError("oh no");
    }
}

Затем в вашем веб-приложении или любом другом конкретном приложении, использующем вашу библиотеку классов, именно там вы на самом деле настраиваете свою реализацию ведения журналов и регистрируете ее через контейнер DI для инъекции.в ваш фасад журналирования.

Короче говоря, ваша библиотека классов зависит только от вашего фасада регистрации, что позволяет ей в общем случае вызывать такие вещи, как LogError.Приложение, которое использует вашу библиотеку, устанавливает свою фактическую конкретную реализацию регистрации, которая затем будет использоваться под капотом фасадом для регистрации библиотеки.

0 голосов
/ 23 октября 2018
  1. Вам не нужен отдельный файл конфигурации.Если ваш основной проект ASP.net MVC имеет nlog.config и он успешно скопирован во время процесса сборки, то такая же конфигурация будет загружена, когда

    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
    
  2. Убедитесь, что вы скопировали файл правильно.Также MinLevel правильно настроен в конфигурации NLog.config.

  3. Убедитесь, что у вас есть .NET Core ClassLibrary (просто чтобы убедиться, что он успешно загружается)

  4. В вашем случае вы также можете использовать Dependency Injection, но это другая история.

Вот полный пример с NLog

  1. Вам нужночтобы получить пакеты NLog и NLog.Web.AspnetCore

  2. в Program.cs

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
         return  WebHost.CreateDefaultBuilder(args)
                    .ConfigureLogging(logging =>
                    {
                        logging.ClearProviders();
                        logging.SetMinimumLevel(LogLevel.Trace);
                    }).UseNLog()
                .UseStartup<Startup>();
        }
    
  3. Теперь в проекте ClassLibrary просто добавьте ссылку для NLog,Примечание: здесь Убедитесь, что ILogger из Microsoft.Extensions.Logging не из NLog.

    public class Class1
    {
        //private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private ILogger<Class1> _logger = null;
        public Class1(ILogger<Class1> logger)
        {
            this._logger = logger;
        }
    
        public void DoStuff()
        {
            var _failed = true;
            if (_failed) _logger.LogError("oh no");
        }
    }
    

Теперь он будет работать без проблем.

...