【问题标题】:How to place a Configuration Source to a certain Configuration Section to avoid key conflicts?如何将配置源放置到某个配置节以避免密钥冲突?
【发布时间】:2023-04-03 09:24:01
【问题描述】:

我有两个配置文件:

users.json:

{
  "Alice" : { "Email": "alice@example.com" },
  "Bob" : { "Email": "bob@example.com" }
}

connections.json

{
  "Database" : { "ConnectionString": "..." },
  "Gateway" : { "Url": "http://..." }
}

我正在尝试编写单个配置根:

var cfg = new ConfigurationBuilder()
    .AddJsonFile("users.json")
    .AddJsonFile("connections.json")
    .Build();

显然,我需要将每个配置源放入它的部分:UsersConnections - 以避免冲突。某种前缀包装器可以完成这项工作,但我不想实现自己的。

如果您无法修改配置文件结构(在实际项目中是有原因的),您将如何处理这种情况?

【问题讨论】:

    标签: c# configuration .net-core .net-standard


    【解决方案1】:

    根据JsonConfigurationFileParserJsonConfigurationProvider 类的实现看起来你只能编写自己的FileConfigurationProvider 实现。


    作为一种解决方法,您可以执行以下操作(逐步):

    • => 读取每个文件的配置
    • => 然后将结果作为 KeyValuePair 项的集合获取
    • => 然后为每个键名附加一些自定义前缀(在您的情况下基于文件名)
    • => 合并:将最终集合作为 MemoryCollection 源附加到根配置

    以下代码为idea实现,在prod中使用前可能需要修改:

    public static class ConfigurationBuilderExtensions
    {
        public static IConfigurationBuilder AddJsonFileWithPrefix(this IConfigurationBuilder configurationBuilder, string fileName, string prefix) 
        {
            var config = new ConfigurationBuilder()
                // you may need to set up base path again here
                // .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile(fileName).Build();
    
            var result = new List<KeyValuePair<string, string>>();
    
            foreach(var pair in config.AsEnumerable())
            {
                result.Add(new KeyValuePair<string, string>($"{prefix}:{pair.Key}", pair.Value));
            }
    
            return configurationBuilder.AddInMemoryCollection(result);
        }
    } 
    

    那么您可以创建配置根目录为:

    var cfg = new ConfigurationBuilder()
        .AddJsonFileWithPrefix("users.json", "users")
        .AddJsonFileWithPrefix("connections.json", "connections")
        .Build();
    

    【讨论】:

    • 感谢您的样品。如果您要改进它,只有几个问题:1)重新加载机制不起作用; 2)可以使它更通用(不仅适用于json)
    【解决方案2】:

    您可以修改 json 文件以反映部分:

    users.json:

    {
        "Users": {
            "Alice" : { "Email": "alice@example.com" },
            "Bob" : { "Email": "bob@example.com" }
        }
    }
    

    和connections.json

    {
        "Connections": {
            "Database" : { "ConnectionString": "..." },
            "Gateway" : { "Url": "http://..." }
        }
    }
    

    【讨论】:

    • 一般来说,这很容易反对配置去规范化,但在我的情况下,它根本不是修改这些文件的选项
    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 2019-10-16
    • 2016-01-28
    • 2020-11-04
    相关资源
    最近更新 更多