使用 NLog 进行依赖注入

Dependency Injection wth NLog

我有一个 .NET Core Web 应用程序,我正在尝试通过 NLog 添加日志记录。 在以前的项目中,我只是在每个 class:

的顶部使用了类似下面的内容
private static Logger logger = LogManager.GetCurrentClassLogger();

我正在尝试尽可能遵循此项目的更多最佳实践。

我的问题是,我如何才能注入一个记录器,它具有被注入的 class 的完全限定名称?

在我的 startup.cs 文件中,到目前为止我有以下内容:

services.AddScoped<BLL.Logging.NLogLogger>();

目前,NLogLogger class 通过 GetCurrentClassLogger() 创建了一个 NLog Logger 实例,使用时只会将名称报告为“BLL.Logging.NLogLogger " 而不是记录器被注入的实际 class。

为了简化问题并使其更通用: 您如何传入 .NET Core 将要向其中注入 class 的 class 的名称?

我想过类似下面的事情,但不确定如何实现它:

services.AddScoped<BLL.Logging.NLogLogger>(serviceProvider => new BLL.Logging.NLogLogger("class name here"));

我想我已经找到了一个可以接受的解决方案,尽管与我提出问题的方式不完全相同。

首先,我创建了一个“LoggerFactory”,它有一个名为“GetLogger”的方法(它创建了具体的 NLog Logger 并接受一个 class 名称作为参数),然后我将其注入工厂而不是直接记录器。

LoggerFactory:

public class LoggerFactory : ILoggerFactory
{
    public ILogger GetLogger(string fullyQualifiedClassName)
    {
        return new NLogLogger(fullyQualifiedClassName);
    }
}

NLogLogger:

public class NLogLogger : ILogger, INLogLogger
{
    NLog.Logger mylogger;
    public NLogLogger(string fullyQualifiedClassName)
    {
        mylogger = NLog.LogManager.GetLogger(fullyQualifiedClassName);
    }
}

Startup.cs:

services.AddScoped<BLL.Logging.ILoggerFactory>();

在我的控制器中 class,我有:

    private BLL.Logging.ILogger logger;//my NLogLogger inherits this interface

    public HomeController(BLL.Logging.ILoggerFactory loggerFactory)
    {
        logger = loggerFactory.GetLogger(this.GetType().FullName);
    }

所以我现在有效地完成了,而不是注入实际的 Logger 本身(@Steven 表示不可能按照我尝试这样做的方式),而是注入了实用程序来创建包装 NLog 的记录器实例。

我仍然有责任在 class 中创建记录器,但至少我已经与底层日志记录框架 (NLog) 分离。

使用 DI 指定 ILogger<T> 类型而不是 Logger,其中 T 是使用记录器的 class 类型,因此 NLog 将知道 class.例如:

public class TodoController : Controller
{
    private readonly ILogger _logger;

    public TodoController(ILogger<TodoController> logger)
    {
        _logger = logger;
    }
}

参考文献: