一、前言
配置的本质就是字符串的键值对,微软的一系列接口其实就是对这些键值对字符串的抽象。
二、基本类型
2.1、Nuget包
- Microsoft.Extensions.Configuration.Abstractions
- Microsoft.Extensions.Configuration
2.2、抽象接口
- IConfiguration
- 提供了查询、设置配置项、监控变化等方法
- IConfigurationRoot
- 在IConfiguration接口基础上,增加了 Reload 方法强制从provider中重新加载配置值
- IConfigurationSection
- 对配置节点的抽象
- IConfigurationBuilder
- 根据提供的数据源注册并构建IConfiguration
- IConfigurationSource
- 对数据源的抽象,例如Json、xml、环境变量、内存变量等
- IConfigurationProvider
- 规定了配置项的获取、设置、重载等统一的行为
三、基本配置
注:各种配置方式的目的是在控制台中输出以下内容,如下图:
3.1、加载内存中的配置
- 需要引入包:Microsoft.Extensions.Configuration
- 主要方法:builder.AddInMemoryCollection()
static void Main(string[] args)
{
IConfigurationBuilder builder = new ConfigurationBuilder();
var memoryData = new Dictionary<string, string>();
memoryData.Add("Student:Code", "10002385");
memoryData.Add("Student:Name", "LiuSan");
builder.AddInMemoryCollection(memoryData);
IConfigurationRoot configurationRoot = builder.Build();
IConfigurationSection configurationSection = configurationRoot.GetSection("Student");
Console.WriteLine($"Code:{configurationSection["Code"]}");
Console.WriteLine($"Name:{configurationSection["Name"]}");
Console.Read();
}
3.2、加载环境变量中的配置
- 需要引入包:Microsoft.Extensions.Configuration.EnvironmentVariables
- 主要方法:builder.AddEnvironmentVariables()
- 环境变量中层级关系使用 __ 代替 :
1 static void Main(string[] args)
2 {
3 IConfigurationBuilder builder = new ConfigurationBuilder();
4 builder.AddEnvironmentVariables();
5 IConfigurationRoot configurationRoot = builder.Build();
6 IConfigurationSection configurationSection = configurationRoot.GetSection("Student");
7
8 Console.WriteLine($"Code:{configurationSection["Code"]}");
9 Console.WriteLine($"Name:{configurationSection["Name"]}");
10
11 Console.Read();
12 }
3.3、加载命令行中的配置
- 需要引入包:Microsoft.Extensions.Configuration.CommandLine
- 主要方法:builder.AddCommandLine(args)
- 命令行中使用--表示配置项,层级关系使用:
1 static void Main(string[] args)
2 {
3 IConfigurationBuilder builder = new ConfigurationBuilder();
4 builder.AddCommandLine(args);
5 IConfigurationRoot configurationRoot = builder.Build();
6 IConfigurationSection configurationSection = configurationRoot.GetSection("Student");
7
8 Console.WriteLine($"Code:{configurationSection["Code"]}");
9 Console.WriteLine($"Name:{configurationSection["Name"]}");
10
11 Console.Read();
12 }
3.4、加载Json中的配置
- 需要引入包:Microsoft.Extensions.Configuration.Json
- 主要方法:builder.AddJsonFile("appsettings.json")
1 static void Main(string[] args)
2 {
3 IConfigurationBuilder builder = new ConfigurationBuilder();
4 builder.AddJsonFile("appsettings.json");
5 IConfigurationRoot configurationRoot = builder.Build();
6 IConfigurationSection configurationSection = configurationRoot.GetSection("Student");
7
8 Console.WriteLine($"Code:{configurationSection["Code"]}");
9 Console.WriteLine($"Name:{configurationSection["Name"]}");
10
11 Console.Read();
12 }
3.5、加载xml中的配置
- 需要引入包:Microsoft.Extensions.Configuration.Xml
- 主要方法:builder.AddXmlFile("appsettings.xml")
- xml中不会读取最外层,所以Section必需从第二层开始
1 static void Main(string[] args)
2 {
3 IConfigurationBuilder builder = new ConfigurationBuilder();
4 builder.AddXmlFile("appsettings.xml");
5 IConfigurationRoot configurationRoot = builder.Build();
6 IConfigurationSection configurationSection = configurationRoot.GetSection("Student");
7
8 Console.WriteLine($"Code:{configurationSection["Code"]}");
9 Console.WriteLine($"Name:{configurationSection["Name"]}");
10
11 Console.Read();
12 }
四、高级配置
4.1、将配置绑定至强对象
- 需要引入包:Microsoft.Extensions.Configuration.Binder
- 主要方法:configurationRoot.GetSection("Student").Bind(student)
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 IConfigurationBuilder builder = new ConfigurationBuilder();
6 builder.AddJsonFile("appsettings.json");
7 IConfigurationRoot configurationRoot = builder.Build();
8
9 var student = new Student();
10 configurationRoot.GetSection("Student").Bind(student);
11
12 Console.WriteLine($"Code:{student.Code}");
13 Console.WriteLine($"Name:{student.Name}");
14
15 Console.Read();
16 }
17 }
18
19 class Student
20 {
21 public string Code { get; set; }
22
23 public string Name { get; set; }
24 }
4.2、IOptions
- 需要引入包:Microsoft.Extensins.Options
- 需要引入包:Microsoft.Extensions.Options.ConfigurationExtensions
- 本质其实就是将一个Section配置节点映射到一个实体对象
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 IConfigurationBuilder builder = new ConfigurationBuilder();
6 builder.AddJsonFile("appsettings.json");
7 IConfigurationRoot configurationRoot = builder.Build();
8
9 IServiceCollection services = new ServiceCollection();
10 services.Configure<WeixinOptions>(configurationRoot.GetSection("WeixinSetting"));
11 services.AddScoped<IWeixinService, WeixinService>();
12
13 var provider = services.BuildServiceProvider();
14 var weixinService = provider.GetService<IWeixinService>();
15 string appId = weixinService.AppId;
16 string token = weixinService.Token;
17
18 Console.Read();
19 }
20 }
21
22 interface IWeixinService
23 {
24 string AppId { get; }
25 string Token { get; }
26 }
27
28 class WeixinService: IWeixinService
29 {
30 IOptions<WeixinOptions> _options;
31 public WeixinService(IOptions<WeixinOptions> options)
32 {
33 _options = options;
34 }
35
36 public string AppId { get => _options.Value.AppId; }
37 public string Token { get => _options.Value.Token;}
38 }
39
40 class WeixinOptions
41 {
42 public string AppId { get; set; }
43
44 public string Token { get; set; }
45 }
4.3、热更新
- IConfigurationBuilder添加数据源时设置reloadOnChange=true
- 监听的核心方法:var token = configurationRoot.GetReloadToken()
1 static void Main(string[] args)
2 {
3 IConfigurationBuilder builder = new ConfigurationBuilder();
4 builder.AddJsonFile("appsettings.json", optional:false, reloadOnChange:true);
5 IConfigurationRoot configurationRoot = builder.Build();
6 IConfigurationSection configurationSection = configurationRoot.GetSection("Student");
7
8 var token = configurationRoot.GetReloadToken();
9 ChangeToken.OnChange(() => configurationRoot.GetReloadToken(), () =>
10 {
11 Console.WriteLine("配置发生改变了...");
12 Console.WriteLine($"Code:{configurationSection["Code"]}");
13 Console.WriteLine($"Name:{configurationSection["Name"]}");
14 });
15
16 Console.Read();
17 }
五、总结
- 配置就是key-value键值对字符串
- IConfiguration和IConfigurationRoot是对键值对的抽象
- IConfigurationBuilder用于构建IConfiguration和IConfigurationRoot
- IConfigurationSource是对数据源的抽象
- IConfigurationProvider将不同来源的IConfigurationSource 转为统一的模型
- IOptions方便将不同的配置节点(Path)映射为对应的强类型对象
- IConfigurationBuilder添加多个数据源(IConfigurationSource)后,如果key重名,则以最后一个配置为准(覆盖前面)
更多精彩文章,请关注我的公众号:
来源:oschina
链接:https://my.oschina.net/u/4275644/blog/4263149