Dependency Injection With NLog

那年仲夏 提交于 2019-12-04 12:02:51

问题


I've got a .Net core web app that I'm trying to add logging to via NLog. In previous projects, I've just used something like the following at the top of every class:

private static Logger logger = LogManager.GetCurrentClassLogger();

I've trying to follow more best practices with this project where possible.

My question is, how can I inject a logger which has the fully qualified name of the class that it's being injected into?

In my startup.cs file, so far I've got the following:

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

At the moment, the NLogLogger class creates an instance of an NLog Logger via GetCurrentClassLogger(), which when used will only ever report the name as "BLL.Logging.NLogLogger" rather than the actual class that the logger is being injected into.

To simplify the question and make it a big more generic: How can you pass in the name of the class that .Net Core is going to inject a class into?

I've thought about something like the below, but not sure how to achieve it:

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

回答1:


Using DI specify ILogger<T> type instead of Logger, where T is the class type that uses the logger, so NLog will know about the class. For example:

public class TodoController : Controller
{
    private readonly ILogger _logger;

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



回答2:


I think I've figured out an acceptable solution, although not exactly the way I asked the question.

First of all, I create a "LoggerFactory", which has a single method called "GetLogger" (which creates the concrete NLog Logger and accepts a class name as a parameter), and I inject this factory instead of the logger directly.

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>();

The in my controller class, I've got:

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

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

So what I've effectively now done, is rather than injecting the actual Logger itself (Which @Steven indicated would not be possible the way I was trying to do it), I've instead injected the utility to create an instance of a logger which wraps NLog.

I've still got the responsibility to create the logger within the class, but at least I've decoupled from the underlying logging framework (NLog).



来源:https://stackoverflow.com/questions/41534253/dependency-injection-with-nlog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!