NLog 适用于 ASP.NET Core 应用程序,但不适用于 .NET Core xUnit 测试项目

Dou*_*son 1 c# nlog .net-core asp.net-core

我创建了一个 .NET Core 类库,它定义实用程序类接口并实现每个接口,例如通过 ADO.NET 访问数据库等。

每个实现类都使用 NLog。这在包含并引用 .NET Core 类库的 ASP.NET Core Web 应用程序中非常有效。

但是,当我尝试在 .NET Core xUnit Test 项目的上下文中实例化这些相同的实现类时,我得到

无法将“NLog.Logger”类型的对象转换为“Microsoft.Extensions.Logging.ILogger”类型

我搜索过类似的问题但没有找到。

在每个类中我都声明了一个私有只读变量:

private readonly ILogger<DatabasePersistenceAdoDotNet> _logger = null;
Run Code Online (Sandbox Code Playgroud)

我像这样实例化这个变量:

_logger = (ILogger<DatabasePersistenceAdoDotNet>)NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
Run Code Online (Sandbox Code Playgroud)

这在包含并引用 .NET Core 类库的 ASP.NET Core Web 应用程序中有效,但在我的 .NET Core xUnit Test 项目中却崩溃了。

我怀疑这与 ASP.NET 的依赖项注入在 .NET Core xUnit Test 项目中不可用有关,但我无法弄清楚如何使我的实用程序包在这两种情况下都能正常工作。

Jul*_*ian 5

当将 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);
Run Code Online (Sandbox Code Playgroud)

请注意,您不能以Microsoft.Extensions.Logging.ILogger<MyClass>这种方式创建!只是一个非通用的Microsoft.Extensions.Logging.ILogger. 如果您需要通用版本,那么您需要 DI 设置,它将处理两者之间的转换。

NLog.config 和测试项目

另外,很高兴知道,在测试项目中找到 nlog.config 很困难,因为单元测试框架会移动二进制文件等。我建议使用配置 API

例如

var configuration = new LoggingConfiguration();
configuration.AddRuleForAllLevels(new ConsoleTarget());
LogManager.Configuration = configuration;
Run Code Online (Sandbox Code Playgroud)

或者

var configuration = XmlLoggingConfiguration.CreateFromXmlString("<nlog>....</nlog>"); //full nlog.config as string
LogManager.Configuration = configuration;
Run Code Online (Sandbox Code Playgroud)