Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从库代码使用Microsoft.Extensions.Logging?_C#_Logging - Fatal编程技术网

C# 如何从库代码使用Microsoft.Extensions.Logging?

C# 如何从库代码使用Microsoft.Extensions.Logging?,c#,logging,C#,Logging,我很难理解在通用库中使用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的最佳方式是什么

使用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");
    }
}
公共类MyClass
{
专用只读Ilogger记录器;
公共MyClass(ILogger记录器)
{
记录器=记录器;
}
公共图书馆
{
Logger.LogInformation(“foo”);
}
}
所以现在我需要在ctor上通过一个ILogger。
好的,没问题,我可以从工厂买一个。
现在我需要一个工厂

  • 我在哪里能找到一家工厂?我只是为我的库创建一个全局库
  • 客户端将如何配置工厂以添加所需的iLogger提供程序
  • 如果客户端配置正确,iLogger工厂是否会自动配置正确的提供程序
这听起来是错误的,因为要在库代码中创建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>());
//客户端代码
var myClass=新的myClass()//非直瞄
var myClass=newmyclass(loggerFactory.CreateLogger());
首先,代码很糟糕,现在客户端必须跟踪某个地方的iLogger工厂

我是否错过了一些东西,或者Microsoft.Extensions.Logging对于常规库来说很糟糕?您是否有使用Microsoft.Extensions.Logging的此类项目的代码示例


谢谢

听起来您遇到了开发人员遇到的一个常见问题库

最终,在依赖注入被视为默认的环境中(请参见.NET core等),知道应该如何处理这一点是很棘手的

不久前我问了一个类似的问题:

我甚至还编写了一个实用程序库(),该库设计得很糟糕,旨在帮助从库的角度抽象DI容器

然而,在您的例子中,我可以理解为什么NLog与.NET日志记录方法相比看起来更优雅,但我在这里说这是一种错误的安慰

NET日志抽象使用的构造函数参数遵循,而NLog解决方案完全隐藏了依赖关系,更不用说允许您替换它了

我同意,如果没有一个支持依赖注入的环境,它会变得有点麻烦,但这通常是一个好迹象,表明依赖注入是您可能想要添加的东西

因此,是的,您的库类应该将记录器作为参数,调用方应该通过依赖项容器解析您的类型,或者必须显式地提供记录器实例

tl;博士 您不(也不应该)在库中创建记录器工厂,相反,使用库的应用程序应该对此负责;如果他们使用的是支持host builder和依赖项注入的.NET环境,则平台将为他们解决这一问题

我建议您温习一下Microsoft文档:


它是
asp.net core
项目吗?如果链接有用,请向上投票——不,我不在
asp.net core
项目中。您共享的链接很好地恢复了我的情况:
在MVC控制器之外访问日志API OK,因此,这就是新的日志API很快成为噩梦的地方。
我看到的最佳解决方案是库的静态配置:
创建一个位于中心位置的静态类或项目,以保存并环绕主LoggerFactory引用:我认为这是最佳解决方案,除非您不使用任何具有并发性的提供程序问题。
这个问题并非“仅仅”基于观点,即使它确实包含一些自以为是的措辞。它正在寻找如何在一个特定的环境中完成这项任务——一个独立于“公共DI”技术的任意库。这一点尤其重要,因为即使是LibLog(现在已经不存在了)也遵从“使用Logging.Abstractions”,而没有一种有用的方法来实现这一点。直接使用NLog(建立库依赖关系,这是另一个问题)和LibLog(使用“一个”可用的提供者)都隐式地避免了这一问题。如果存在像应用程序这样的“复杂”层次结构,这甚至需要处理