NLog可在ASP.NET Core App中使用,但不能在.NET Core xUnit Test Project中使用

时间:2019-06-10 23:41:21

标签: c# asp.net-core .net-core nlog

我已经创建了一个.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;

我正在像这样实例化此变量:

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

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

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

1 个答案:

答案 0 :(得分:1)

将NLog与ASP.NET Core结合使用时,有两种样式:

  1. 使用GetCurrentClassLogger()的非DI样式
  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很难,因为单元测试框架会移动二进制文件等。我建议使用config API

例如

var configuration = new LoggingConfiguration();
configuration.AddRuleForAllLevels(new ConsoleTarget());
NLog.Web.NLogBuilder.ConfigureNLog(configuration);

OR

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