【发布时间】:2020-04-07 08:26:39
【问题描述】:
我很难理解在通用库中使用 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。
- 从哪里获得 ILoggerFactory?我只是为我的图书馆创建一个全球性的?
- 客户端将如何配置工厂以添加他想要的 ILoggerProvider?
- 如果客户端已正确完成配置,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>());
首先代码很糟糕,现在客户端必须在某处跟踪 ILoggerFactory。
我是否错过了什么或 Microsoft.Extensions.Logging 对于通用库来说看起来很糟糕?您是否有使用 Microsoft.Extensions.Logging 的此类项目的代码示例?
谢谢
【问题讨论】:
-
是
asp.net-core项目吗? -
不,我不在
asp.net-core项目中。您的共享链接恢复了我的情况:Accessing the Logging API Outside of a MVC Controller OK, so this is where the new logging API quickly becomes a nightmare.我看到的最佳解决方案是库的静态配置:Create a centrally located static class or project to hold and wrap around the main LoggerFactory reference: I see this as the best solution here unless you aren’t using any providers that have concurrency issues. -
这个问题不“仅仅”基于意见,即使它确实包含一些自以为是的措辞。它正在寻找如何在特定上下文中完成这项任务 - 独立于“通用 DI”技术的任意库。这尤其重要,因为即使是 LibLog(现已不复存在)也遵循“使用 Logging.Abstractions”而没有如何做到这一点的有用方法。
-
直接使用 NLog(建立库依赖关系,这是另一个问题)和 LibLog(使用“一个”可用的提供程序)都隐含地没有这个问题。如果有任何类型的“复杂”层次结构,例如 App ,这甚至需要处理