前言
配置对于程序来说,绝对是必不可少,毕竟配置是应用或组件动态适应各种环境的最优方案,没有之一(我还年轻,我是这么认为的);之前可能用的最多的配置源是命令行、文件(XML、Json、INI),Web中对于Asp.Net程序员Web.Config是接触的再多不过了,不管怎样,读取配置信息是避免不了啦,但是对于各种配置源不同及格式不同,又得专门开发对应的配置解析程序;不慌,.NetCore内置的配置框架为此一解烦恼,开箱即用,正文详解,走起~~~
正文
体验之前,简单聊聊有关配置的几个核心类型及其对应的联系;
IConfiguration:暴露给我们使用的配置对象,其实是底层将不同数据结构的原始数据提取,并进行封装成一个具有树形化层次结构的IConfiguration对象;根节点和其他配置节点都继承IConfiguration;
namespace Microsoft.Extensions.Configuration {public interface IConfiguration{// 索引访问 string this[string key] { get; set; }// 指定Key获取 配置节点 IConfigurationSection GetSection(string key);// 配置子节点 IEnumerable<IConfigurationSection> GetChildren();// 用于配置变化通知使用 IChangeToken GetReloadToken();} }
IConfigurationRoot:根节点,配置的根;
namespace Microsoft.Extensions.Configuration
{public interface IConfigurationRoot : IConfiguration{// 对配置数据的重新加载,因为是根,所以会重新加载全部数据void Reload();// 用于不同配置源获取获取数据IEnumerable<IConfigurationProvider> Providers { get; }}
}
IConfigurationSection:其他配置节点,可以理解为子节点;
namespace Microsoft.Extensions.Configuration
{public interface IConfigurationSection : IConfiguration{// 数据指定Key值string Key { get; }// 逻辑树的路径,层次用冒号:隔开,如SectionA:SectionBstring Path { get; }// 承载的配置数据string Value { get; set; }}
}
关系图如下:
IConfigurationProvider:真正读取原始配置的数据,并将其转换成一个中间字典的结构,最后再封装成IConfiguration;
namespace Microsoft.Extensions.Configuration {public interface IConfigurationProvider{ // 获取指定Key的值bool TryGet(string key, out string value);// 设置对应Key值void Set(string key, string value);IChangeToken GetReloadToken();// 加载配置数据void Load();// 获取指定配置节点所有子节点KeyIEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath);} }
IConfigurationSource:原始配置源的体现,每种配置源都会有一个实现该接口的实现类,由于真正读取配置数据是委托IConfigurationProvider对象进行读取的,所以IConfigurationSource的作用就是为了提供IConfigurationProvider对象;
namespace Microsoft.Extensions.Configuration {public interface IConfigurationSource{// 提供对应的 IConfigurationProvider对象IConfigurationProvider Build(IConfigurationBuilder builder);} }
IConfigurationBuilder:将IConfigurationSource配置源注册进行,通过调用其Build方法构造出IConfiguration;
namespace Microsoft.Extensions.Configuration {public interface IConfigurationBuilder{IDictionary<string, object> Properties { get; }// 保存所有注册进来的 配置源 IList<IConfigurationSource> Sources { get; }// 注册配置源 IConfigurationBuilder Add(IConfigurationSource source);// 构造出一个Root对象,然后通过root对象就能获取p,并获取对应上面的值 IConfigurationRoot Build();} }
核心对象关系总结:
IConfigurationProvider真正读取配置数据,并将其封装为中间字典;
同的配置源IConfigurationSource提供对应的IConfigurationProvider对象;
通过IConfigurationBuilder将不同的IConfigurationSource配置源进行注册,并创建出对应的IConfiguration对象;
通过创建的IConfiguration对象就可以获取指定节点的值;
核心类型及其关系就简单说这么多,接下来对不同配置源进行使用体验一把,接下来用一个控制台程序进行演示,老规矩,先通过Nuget安装核心包:
开始撸代码:
内存配置源
运行结果:
命令行配置源
命令行支持的格式:
A. 无前缀的 key=value模式
B. 双中横线模式 --key=value或 --key value
C. 正斜杠模式 /key=value或 /key value
开撸:
增加命令行扩展包:
模拟命令行传参,两种方式:
项目属性里面配置
直接在launchSettings.json中配置
代码
运行结果
文件配置源
通过Nuget安装对应文件类型的包,如下
准备xml、json、ini三个配置源不同的文件
代码应用
运行,正常获取值
环境变量配置源
在之前,估计想不到合适的应用场景将环境变量作为配置源,对不对,如果有,那应该不多;但是现如今docker的存在,让其变得常用,因为毕竟容器的隔离使得环境变量可以针对对应的容器进行配置;
通过Nuget安装包
模拟环境变量配置
代码走起
运行结果
总结
这里先写到这吧,太晚了(明天整理一下发出),这里大概说了几个关键类型的作用及关系,然后针对不同配置源进行举例演示,用法基本上都是这样,是不是很简单;下次咱们聊聊热更新;