Serilog JSON 配置中的 "Using" 有什么作用?

What does "Using" in Serilog JSON configuration do?

在 Serilog JSON 配置中 Using 实际上做了什么(例如在 .Net Core 环境中的 AppSettings.json 文件中)?

让我们以这个配置为例:

"Serilog": {
  "Using": [ "Serilog.Sinks.Console" ], <=======***HERE***=========
  "MinimumLevel": "Debug",
  "WriteTo": [
    { "Name": "Console" },
    {
      "Name": "RollingFile",
      "Args": {
        "pathFormat": "logs\log-{Date}.txt",
        "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
      }
    }
  ],
  "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
  "Properties": {
    "Application": "My Application"
  }
}

在上面的示例中,我们使用了 File sink WITHOUT 将其添加到 Using 属性。但是,似乎一切正常。

所以我不明白为什么我们基本上需要这个 Using。有人可以给我解释一下吗?

这包含在 Serilog.Settings.Configuration 的文档中:

(This package implements a convention using DependencyContext to find any package with Serilog anywhere in the name and pulls configuration methods from it, so the Using example above is redundant.)

这意味着它用于定义哪些包用于定位 Serilog 接收器,但在使用 Serilog.Settings.Configuration 包时它是多余的。


更多信息

我查看了 Serilog 源代码,以便能够提供更多关于 Using 的确切功能以及为什么首先需要它的信息。希望以下解释对您有所帮助。

考虑以下基于代码的设置:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

在此示例中,ConsoleLoggerSinkConfiguration 的扩展方法(因此它采用 LoggerSinkConfiguration 的实例作为其第一个参数)。使用这种基于代码的方法时,仅当可以在引用的程序集中找到此扩展方法时,代码才会编译。

接下来,考虑以下方法,它使用基于 IConfiguration 的方法:

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(someConfiguration)
    .CreateLogger();
{
    "Serilog": {
        "Using": ["Serilog.Sinks.Console"], // Redundant.
        "WriteTo": ["Console"]
    }
}

在此示例中,编译过程不知道 JSON 字符串值 "Console" 指的是什么,因此需要一个可以从字符串 "Console" 到上面提到的 Console() 扩展方法。为了做到这一点,Serilog 需要首先 找到 扩展方法 在运行时 (在这个例子中,它位于 Serilog.Sinks.Console 组装)。

这个查找过程是使用反射完成的,它在寻找这些扩展方法时对 find public static methods that take as their first parameter a LoggerSinkConfiguration. The Using directive you've asked about in your question is a mechanism for helping determine exactly which assemblies should be scanned 进行了一些汇编扫描。

如文档所述,基于 IConfiguration 的方法使用 DependencyContext 以便在使用此方法时 automatically scan assemblies that have Serilog in their name. Because Serilog.Sinks.Console does have Serilog in its name, there's no need to add this to the Using directive. You also have the option to provide your own DependencyContext instance,因此您可能需要明确说明要使用哪些程序集寻找水槽时扫描。