我很难理解在通用库中使用 Microsoft.Extensions.Logging 的最佳方法是什么。
使用 NLog,您可以执行以下操作:
public class MyClass
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public void foo()
{
Logger.Info("foo");
}
}
Run Code Online (Sandbox Code Playgroud)
你完成了!您让客户端配置其目标,但这不再是您的问题。
但是使用 Microsoft.Extensions.Logging 代码看起来更像:
public class MyClass
{
private readonly Ilogger Logger;
public MyClass(ILogger<MyClass> logger)
{
Logger = logger;
}
public void foo()
{
Logger.LogInformation("foo");
}
}
Run Code Online (Sandbox Code Playgroud)
所以现在我需要在 ctor 上传递一个 ILogger。
好吧没问题我可以从 ILoggerFactory 得到一个。
现在我需要一个 ILoggerFactory。
这听起来是错误的,因为在库代码中创建 LoggerFactory 需要引用 Microsoft.Extensions.Logging 而你应该只引用 Microsoft.Extensions.Logging.Abstractions。这是代码异味的线索。
当您在 ASP.Net Core 应用程序或服务中但想要一个可以在控制台应用程序或 WinForm/WPF 应用程序中使用的通用库时,构造函数中的依赖注入看起来不错?
那么现在客户端现在需要传递一个 ILogger 吗?
//Client code
var myClass = new MyClass(); //with NLog
var myClass = new MyClass(loggerFactory.CreateLogger<MyClass>());
Run Code Online (Sandbox Code Playgroud)
首先,代码很糟糕,现在客户端必须在某处跟踪 ILoggerFactory。
我是否错过了某些东西,或者 Microsoft.Extensions.Logging 对于通用库来说看起来很糟糕?您是否有使用 Microsoft.Extensions.Logging 的此类项目的代码示例?
谢谢
听起来您遇到了库开发人员偶然发现的常见问题。
最终,在依赖注入被视为默认的环境中(参见 .NET core 等),了解如何处理它可能很棘手。
其实我不久前也问过类似的问题:
我什至编写了一个实用程序库(https://github.com/ckpearson/IoCBridge),该库构思不善,旨在帮助从库的角度抽象 DI 容器。
然而,就您的情况而言,我可以理解为什么 NLog 看起来比 .NET 日志记录方法更优雅,但我在这里要说的是,这是一种虚假的安慰。
.NET 日志记录抽象使用的构造函数参数遵循显式依赖关系原则,而 NLog 解决方案完全隐藏了依赖关系,更不用说允许您替换它了。
我同意,如果没有支持依赖注入的环境,它会变得有点麻烦,但这通常是一个好兆头,表明依赖注入是您可能想要添加的东西。
所以,是的,您的库类应该将记录器作为参数,并且调用者应该通过依赖项容器解析您的类型,或者应该必须显式提供记录器实例。
您不会(也不应该)在您的库中创建记录器工厂,相反,使用您的库的应用程序应该对此负责;如果他们使用支持主机构建器和依赖项注入的 .NET 环境,平台将为他们处理这个问题。
我建议温习一下 Microsoft 文档:
| 归档时间: |
|
| 查看次数: |
1570 次 |
| 最近记录: |