Skip to main content

Part2 配置系统

读取配置文件

var configBuilder = new ConfigurationBuilder();
configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);
var config = configBuilder.Build();
var name = config["name"];
Console.WriteLine(name);
var add = config.GetSection("proxy:add").Value;
Console.WriteLine(add);

var add2 = config.GetSection("proxy").Get<ProxyConfig>();
Console.WriteLine(add2.Add);



public class ProxyConfig
{
    public string Add { get; set; }
}

选项方式读取配置

读取配置时, 有3种方式

  • IOptions<T>
    • 配置改变后, 不能读取到新的值, 必须重启程序才可以读到新的值
    • 不监听配置的改变, 资源占用较少, 适用于对服务器启动后就不会改变的值进行读取
  • IOptionsMonitor<T>
    • 在配置改变后, 总能读到新的值
  • IOptionsSnapshot<T>
    • 在一个作用范围(如 Scope)内配置的值会保持一致(即使期间值更新了), 当离开作用范围后再次进入范围时, 才会读取到最新的值
    • 使用 IOptionsSnapshot 更符合大部分场景的需求

 

使用命令行或环境变量时, 对于复杂结构的配置, 需要采用层级配置, 如: Proxy:Add=1000, 表示 Proxy 对象中的 Add 属性值为1000, 如果是数组, 就是这样: Num:0=1, Num:1=2

var configBuilder = new ConfigurationBuilder();

// 通过json文件
// configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);

// 通过命令行 
//configBuilder.AddCommandLine(args);

// 通过环境变量(一般加个前缀, 避免和其它环境变量混在一块)
configBuilder.AddEnvironmentVariables();

var configRoot = configBuilder.Build();

ServiceCollection services = new ServiceCollection();
services.AddOptions().Configure<ProxyConfig>((e) => { configRoot.Bind("proxy", e); });
services.AddScoped<TestConfigConroller>();

using (var sp = services.BuildServiceProvider())
{
    while (true)
    {
        // 创建Scope来产生一个范围, IOptionsSnapshot在这个范围内保持数值一致, 离开作用范围之后, 重新获取数值时会取得最新的值
        using (var sc = sp.CreateScope())
        {
            var tc = sc.ServiceProvider.GetRequiredService<TestConfigConroller>();
            tc.Test();
            
            Console.WriteLine("更改配置文件, 可以发现下边读出来的值还是一样的");
            Console.ReadKey();
            
            var tc2 = sc.ServiceProvider.GetRequiredService<TestConfigConroller>();
            tc2.Test();
        }

        Console.WriteLine("出Scope的范围了, 按下以继续");
        Console.ReadKey();
    }
    
}



public class TestConfigConroller
{
    private readonly IOptionsSnapshot<ProxyConfig> _proxyConfig;


    public TestConfigConroller(IOptionsSnapshot<ProxyConfig> proxyConfig)
    {
        _proxyConfig = proxyConfig;
    }

    public void Test()
    {
        Console.WriteLine(_proxyConfig.Value.Add);
        Console.WriteLine("----------");
        Console.WriteLine(_proxyConfig.Value.Add);
    }
    
}

config.json

{
  "name": "abc",
  "proxy": {
    "add": "192.168"
  }
}