我有一个.Net核心网络应用,我试图通过NLog添加日志记录。 在以前的项目中,我只是在每个班级的顶部使用了类似下面的内容:
private static Logger logger = LogManager.GetCurrentClassLogger();
我尽可能在这个项目中尝试更多最佳实践。
我的问题是,如何注入一个记录器,该记录器具有被注入的类的完全限定名称?
在我的startup.cs文件中,到目前为止我已经得到以下内容:
services.AddScoped<BLL.Logging.NLogLogger>();
目前,NLogLogger
类通过GetCurrentClassLogger()
创建NLog Logger的实例,使用时只会将名称报告为&#34; BLL.Logging.NLogLogger&#34;而不是注入记录器的实际类。
简化问题并使其更具通用性: 你怎么能传入.Net Core将要注入类的类的名称?
我已经考虑过类似下面的内容,但不知道如何实现它:
services.AddScoped<BLL.Logging.NLogLogger>(serviceProvider => new BLL.Logging.NLogLogger("class name here"));
答案 0 :(得分:8)
使用DI指定ILogger<T>
类型而不是Logger
,其中T
是使用记录器的类类型,因此NLog将了解该类。例如:
public class TodoController : Controller
{
private readonly ILogger _logger;
public TodoController(ILogger<TodoController> logger)
{
_logger = logger;
}
}
答案 1 :(得分:6)
我想我已经找到了一个可以接受的解决方案,尽管不完全是我问这个问题的方式。
首先,我创建一个&#34; LoggerFactory&#34;,它有一个名为&#34; GetLogger&#34;的方法。 (创建具体的NLog Logger并接受类名作为参数),我直接注入这个工厂而不是记录器。
<强>的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>();
在我的控制器课程中,我得到了:
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的记录器实例。
我仍然有责任在课堂上创建记录器,但至少我已经与底层记录框架(NLog)分离了。