我很难理解在通用库中使用Microsoft.Extensions.Logging的最佳方法是什么。
使用NLog,您可以做到:
public class MyClass
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public void foo()
{
Logger.Info("foo");
}
}你就完蛋了!您让客户端配置其目标,但这不再是您的问题了。
但是对于Microsoft.Extensions.Logging,代码看起来更像:
public class MyClass
{
private readonly Ilogger Logger;
public MyClass(ILogger<MyClass> logger)
{
Logger = logger;
}
public void foo()
{
Logger.LogInformation("foo");
}
}所以现在我需要在ctor上传递一个ILogger。
好的,没问题,我可以从ILoggerFactory上得到一个。
现在我需要一个ILoggerFactory。
这听起来不对,因为要在库代码中创建LoggerFactory,您需要引用Microsoft.Extensions.Logging,而应该只引用Microsoft.Extensions.Logging.Abstractions。这是暗号气味的线索。
当您在ASP.Net核心应用程序或服务中时,构造函数中的依赖注入看起来很好,但需要一个可以在控制台应用程序或WinForm/WPF应用程序中使用的通用库?
那么现在客户端需要传递一个ILogger吗?
//Client code
var myClass = new MyClass(); //with NLog
var myClass = new MyClass(loggerFactory.CreateLogger<MyClass>());首先,代码很糟糕,现在客户端必须跟踪某个地方的ILoggerFactory。
对于普通库来说,我是错过了什么东西还是Microsoft.Extensions.Logging看起来很糟糕?您有使用Microsoft.Extensions.Logging的这种类型的项目的代码示例吗?
谢谢
发布于 2021-05-24 13:59:17
听起来好像您遇到了一个常见的问题库开发人员。
最终,在依赖项注入被认为是默认的环境中(请参阅.NET核心等),要知道应该如何处理这个问题可能是很棘手的。
我刚才也问过一个类似的问题:
我甚至编写了一个实用程序库(https://github.com/ckpearson/IoCBridge),它的设计错误,可以帮助从库的角度抽象DI容器。
但是,在您的例子中,我可以理解为什么NLog看起来比.NET日志记录方法更优雅,但我想说的是,这是一种错误的安慰。
构造函数参数以.NET日志抽象使用的方式依附于显式依赖原则,而NLog解决方案则完全隐藏了依赖关系,更不用说允许您替换它了。
我同意,如果没有一个支持依赖注入的环境,它会变得有点麻烦,但这通常是一个很好的迹象,表明依赖注入是您可能需要添加的东西。
因此,是的,您的库类应该将记录器作为参数,调用方应该通过依赖容器解析您的类型,或者必须显式地提供记录器实例。
tl;dr
您不需要(也不应该)在库中创建一个记录器工厂,相反,使用库的应用程序应该对此负责;如果它们使用的是支持主机构建器和依赖项注入的.NET环境,平台将为它们处理这个问题。
我建议浏览一下Microsoft文档:
https://stackoverflow.com/questions/59330116
复制相似问题