NLog работает в приложении ASP.NET Core, но не в тестовом проекте .NET Core xUnit - PullRequest
1 голос
/ 11 июня 2019

Я создал библиотеку классов .NET Core, которая определяет интерфейсы служебных классов и реализует каждый интерфейс для таких вещей, как доступ к базе данных через ADO.NET и т. Д.

Каждый класс реализации использует NLog. Это прекрасно работает в веб-приложении ASP.NET Core, которое включает и ссылается на библиотеку классов .NET Core.

Однако, когда я пытаюсь создать экземпляр этих же классов реализации в контексте проекта .NET Core xUnit Test, я получаю

Невозможно привести объект типа 'NLog.Logger' к типу 'Microsoft.Extensions.Logging.ILogger'

Я искал похожие проблемы, но не нашел ни одной.

В каждом классе я объявил личную переменную только для чтения:

private readonly ILogger<DatabasePersistenceAdoDotNet> _logger = null;

И я создаю экземпляр этой переменной следующим образом:

_logger = (ILogger<DatabasePersistenceAdoDotNet>)NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

Это работает в веб-приложении ASP.NET Core, которое включает и ссылается на библиотеку классов .NET Core, но разрывается в моем проекте .NET Core xUnit Test.

Я подозреваю, что это как-то связано с тем, что инъекция зависимостей ASP.NET недоступна в проекте .NET Core xUnit Test, но я не могу понять, как заставить мой пакет утилит работать правильно в обоих контекстах.

1 Ответ

1 голос
/ 11 июня 2019

При использовании NLog с ASP.NET Core существует два стиля:

  1. Стиль без DI, с использованием GetCurrentClassLogger()
  2. Стиль DI, которому необходим пакет NLog.Extensions.Logging / NLog.Web.AspNetCore для моста между NLog и Microsoft.Extensions.Logging.

При использовании .GetCurrentClassLogger() вы получите объект логгера NLog (который реализует NLog.ILogger, а не Microsoft.Extensions.Logging.ILogger).

Так что, если вам нужен Microsoft.Extensions.Logging.ILogger, вы не можете использовать .GetCurrentClassLogger(). Вам необходимо:

  1. Настройте всю систему DI самостоятельно, и конструктор вставит Microsoft.Extensions.Logging.ILogger или
  2. Используйте классы пакета NLog.Extensions.Logging.

Вариант 2 - это простой способ, и я покажу вам, как:

// Load NLog
NLog.Web.NLogBuilder.ConfigureNLog("nlog.config");

// Create provider to bridge Microsoft.Extensions.Logging
var provider = new NLog.Extensions.Logging.NLogLoggerProvider();

// Create logger
Microsoft.Extensions.Logging.ILogger logger = provider.CreateLogger(typeof(MyClass).FullName);

Обратите внимание, вы не можете создать Microsoft.Extensions.Logging.ILogger<MyClass> таким образом! Просто не универсальный Microsoft.Extensions.Logging.ILogger. Если вам нужна общая версия, тогда вам нужна настройка DI, и она будет обрабатывать преобразование между ними.

NLog.config и тестовые проекты

Также полезно знать, что найти nlog.config в тестовом проекте сложно, так как каркасные модульные тесты будут перемещать двоичные файлы и т. Д. Я бы порекомендовал использовать API конфигурации

* * +1036 например,
var configuration = new LoggingConfiguration();
configuration.AddRuleForAllLevels(new ConsoleTarget());
NLog.Web.NLogBuilder.ConfigureNLog(configuration);

ИЛИ

var configuration = XmlLoggingConfiguration.CreateFromXmlString("<nlog>....</nlog>"); //full nlog.config as string
NLog.Web.NLogBuilder.ConfigureNLog(configuration);
...