如何在 appsettings.json 中设置我自己的 KeyGenerator 实例?

How to set my own KeyGenerator instance in appsettings.json?

我已经问过这个问题 here 但我觉得 Whosebug 可能更快。这就是我在 json 配置文件中尝试这样做的方式:

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.AzureTableStorage" ],
    "WriteTo": [
      {
        "Name": "AzureTableStorage",
        "Args": {
          "storageTableName": "Logs",
          "connectionString": "*************",
          "keyGenerator": "MyApp.Serilog.AzureTableStorage.MyKeyGenerator"
        }
      }
    ],
    "MinimumLevel": "Verbose"
  }
}

这是我的生成器实现:

public class MyKeyGenerator : IKeyGenerator
{
    public string GeneratePartitionKey(LogEvent logEvent)
    {
        return Environment.MachineName;
    }

    public string GenerateRowKey(LogEvent logEvent, string suffix = null)
    {
        return SUID.nextId().ToString();
    }
}

显然,.ReadFrom.Configuration 操作抛出 InvalidCastException,因为它试图将字符串内容放入 IKeyGenerator 参数。

我应该如何设置 keyGenerator 参数以确保创建 MyKeyGenerator class 的实例并将其提供给该参数?

我克隆了 serilog-settings-configuration and after digging into the code, I found how they expect the JSON setting value when the actual parameter is an interface (See StringArgumentValue.cs,第 57 到 74 行)。

引用要作为参数传递的类型的正确方法是给出 完整的 class 和程序集名称,用逗号分隔 。 class 也必须有一个 public 默认构造函数

例如:

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.AzureTableStorage" ],
    "WriteTo": [
      {
        "Name": "AzureTableStorage",
        "Args": {
          "storageTableName": "Logs",
          "connectionString": "*************",
          "keyGenerator": "MyApp.Serilog.AzureTableStorage.MyKeyGenerator, MyApp"
        }
      }
    ],
    "MinimumLevel": "Verbose"
  }
}

这样,配置器就可以正确实例化 class!