C#配置系统
读取JSON文件
NuGet两个包:Microsoft.Extensions.Configuration
,Mircosoft.Extensions.Configuration.Json
。
{
"name": "yjw",
"age": 18,
"proxy": {"address": "aa"}
}
需要注意的是,上述json文件,需要设置为”如果较新则复制“,确保在exe同目录下复制该配置文件。
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("config.json", true, true);
IConfigurationRoot configRoot=configurationBuilder.Build();
string name = configRoot["name"];
var age = configRoot["age"];
Console.WriteLine(name);
string address = configRoot.GetSection("proxy:address").Value;
Console.WriteLine(address);
output:
yjw
aa
除了以上的操作,还可以帮定一个类,自动完成配置的读取,NuGet安装:Microsoft.Extensions.Configuration.Binder
。
{
"name": "yjw",
"age": 18,
"proxy": {"address": "aa","port": "80"}
}
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace DITest
{
internal class Program1
{
static void Main()
{
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("config.json", true, true);
IConfigurationRoot configRoot=configurationBuilder.Build();
//GetSection返回IConfigurationSection类型,再使用其Get泛型方法,直接可以得到Proxy类
Proxy proxy =configRoot.GetSection("proxy").Get<Proxy>();
Console.WriteLine($"{proxy.address},{proxy.port}");
Console.ReadKey();
}
}
/// <summary>
/// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
/// </summary>
class Proxy
{
public string address { get; set; }
public int port { get; set; }
}
}
output:
aa,80
当然也可以直接用一个类来bind根节点
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace DITest
{
internal class Program1
{
static void Main()
{
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("config.json", true, true);
IConfigurationRoot configRoot=configurationBuilder.Build();
Config config = configRoot.Get<Config>();
Console.WriteLine($"{config.Proxy.address},{config.Proxy.port},{config.Name},{config.Age}");
Console.ReadKey();
}
}
class Config
{
public string Name { get; set; }
public string Age { get; set; }
public Proxy Proxy { get; set; }
}
/// <summary>
/// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
/// </summary>
class Proxy
{
public string address { get; set; }
public int port { get; set; }
}
}
output:
aa,80,yjw,18
选取方式读取
推荐使用选项方式读取,和DI结合更好,且更好利用”reloadOnChange“机制。
NuGet安装:Microsoft.Extensions.Options
,Microsoft.Extensions.Configuration.Binder
。
读取配置的时候,DI要声明IOptions<T>
,IOptionsMonitor<T>
,IOptionsSnapshot<T>
等类型。IOptions<T>
不会读取到新的值;和IOptionsMonitor
相比,IOptionSnapshot<T>
会在同一个范围内保持一致,因此,建议使用IOptionSnapshot
。
Testontrollers.cs
:
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
namespace DITest
{
internal class TestControllers
{
private readonly IOptionsSnapshot<Config> optConfig;//通过IOptinosSnapshot,将配置类注入
public TestControllers(IOptionsSnapshot<Config> optConfig)//通过IOptinosSnapshot,将配置类注入
{
this.optConfig = optConfig;
}
public void Test()
{
Console.WriteLine(optConfig.Value.Name);//通过optConfig.Value获取Config实例
Console.WriteLine(optConfig.Value.Age);
}
}
}
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
namespace DITest
{
internal class Program1
{
static void Main()
{
ServiceCollection sc = new ServiceCollection();
sc.AddScoped<TestControllers>();//注册TestControllers
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("config.json", true, true);
IConfigurationRoot configRoot=configurationBuilder.Build();
sc.AddOptions().Configure<Config>(e=>configRoot.Bind(e));//注册包裹在IOptionSnapshot中的Config
using(var sp = sc.BuildServiceProvider())
{
var c = sp.GetRequiredService<TestControllers>();
c.Test();
}
Console.ReadKey();
}
}
class Config
{
public string Name { get; set; }
public string Age { get; set; }
public Proxy Proxy { get; set; }
}
/// <summary>
/// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
/// </summary>
class Proxy
{
public string address { get; set; }
public int port { get; set; }
}
}
output:
yjw
18
如果只绑定proxy
:
/// <summary>
/// 只读proxy
/// </summary>
class TestControllers2
{
private readonly IOptionsSnapshot<Proxy> optProxy;
public TestControllers2(IOptionsSnapshot<Proxy> optProxy)
{
this.optProxy = optProxy;
}
public void Test()
{
Console.WriteLine(optProxy.Value.address);
Console.WriteLine(optProxy.Value.port);
}
}
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
namespace DITest
{
internal class Program1
{
static void Main()
{
ServiceCollection sc = new ServiceCollection();
sc.AddScoped<TestControllers>();//注册TestControllers
sc.AddScoped<TestControllers2>();//注册TestControllers2
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("config.json", true, true);
IConfigurationRoot configRoot=configurationBuilder.Build();
sc.AddOptions().Configure<Config>(e=>configRoot.Bind(e)).
Configure<Proxy>(e=>configRoot.GetSection("proxy").Bind(e));//绑定proxy
using(var sp = sc.BuildServiceProvider())
{
var c = sp.GetRequiredService<TestControllers2>();
c.Test();
}
Console.ReadKey();
}
}
class Config
{
public string Name { get; set; }
public string Age { get; set; }
public Proxy Proxy { get; set; }
}
/// <summary>
/// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
/// </summary>
class Proxy
{
public string address { get; set; }
public int port { get; set; }
}
}
output:
aa
80
命令行方式配置
需要NuGet安装Microsoft.Extensions.Configuration.CommandLine
configBuilder.AddCommandLine(args)
参数支持多种格式,比如server=127.0.0.1
,--server=127.0.0.1
,--server 127.0.0.1
,/server=127.0.0.1
,/server 127.0.0.1
在cmd模式下:xxx.exe name=johnyang age=18
就可以得到该参数.
在VS中,可以在调试属性中,直接写入args
扁平化配置
对于环境变量,命令行等简单的键值对结构,如果想要进行复杂结构的配置,需要进行“扁平化处理”,对于配置的名字需要采用“层级配置”。
比如,json中的
{
"a":{"b":"c"},
"d":{e:[3,5,7]}
}
在cmd中配置为:
a:b:=c d:e:0=3 d:e:1=5 d:e:2=7