一、配置简述

  之前在.Net Framework平台开发时,一般配置文件都是xml格式的Web.config,而需要配置其他格式的文件就需要自己去读取内容,加载配置了。.而Net Core支持从命令行、环境变量、文件、内存、Key-per-file中加载配置,其中文件包括xml、ini、json三种文件格式。这里需要说明一下,不论哪种格式的配置文件,加载到程序中最终会以Key/Value形式保存,源码中将所有配置读取出来并保存在  Dictionary<string, string> Data  的字典中。额外说明一下Key-per-file配置方式是以文件名称为key,文件内容为value的形式。

二、源码解析

  点击查看源码,我画了一个主要类之间的逻辑关系图,如下:

实线表示继承关系,每条虚线表示意义已经在上面表明。可以分为4个部分,最终要构建的就是IConfigurationRoot,因为所有的配置都存储在它里面的Providers集合中的Data的字典中。

构建它两条路径,一条通过IConfigurationSource构建IConfigurationProvider,然后通过IConfigurationProvider集合构建IConfigurationRoot,也就是图上标记的1/2两步。

另一条是通过IConfigurationSource集合构建IConfigurationBuilder,在通过Builder方法遍历循环创建创建IConfigurationProvider集合,在通过IConfigurationProvider集合构建IConfigurationRoot。也就是图上的3/4两步。这里只讲文件配置方式,包括xml、ini、json文件。

IConfigurationSource:

  它是配置文件的根本,它表示配置文件本身,比如继承自它的 FileConfigurationSource 里面有个Path属性,表示文件路径,会通过这个Path读取这个文件内容。如我们常用的xml、json、ini文件配置都继承自  FileConfigurationSource 。

IConfigurationProvider:

  前面说了,配置最终会转换为key/value的形式,而 IConfigurationProvider 就是这个装换。比如继承他的 FileConfigurationProvider ,它的构造函数需要传第一个  FileConfigurationSource   ,  FileConfigurationProvider   会根据  FileConfigurationSource   的 path 属性找到对应文件,然后读取配置文件到它的  IDictionary<string, string> Data  中。xml的读取在  XmlConfigurationProvider  中,json文件的读取在  JsonConfigurationProvider  。

        private void Load(bool reload)
{
//删除一些判断逻辑
if (reload)
{
Data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
using (var stream = file.CreateReadStream())
{
          //这一步会将文件里面的配置 放到Data中 不同的文件格式Load方法都有对应的实现,这里就不细看了。
Load(stream);
} OnReload();

  一个 IConfigurationProvider 的实现类中会包含一个对应的  IConfigurationSource  的实现类,比如  JsonConfigurationProvider  类中包含一个 JsonConfigurationProvider

IConfigurationRoot:

  所有的类最终构建的目标就是IConfigurationRoot,它包含一个 IList<IConfigurationProvider> _providers 集合,而每一个  IConfigurationProvider  包含一个  IDictionary<string, string> Data  ,所以现在你现在是不是有提花灌顶的感觉。这样做的目的是一个程序可能有多个配置文件,可能有一个xml文件、一个json文件、一个Ini文件。每个配置文件会被读取到对应的  ConfigurationSource  中,然后通过它构建对应的  ConfigurationProvider  ,然后用三个  ConfigurationProvider  构建  ConfigurationRoot  。

那这样会有一个问题,比如xml文件配置了 A的值为1,json文件也配置名称为A的值为2,那会获取谁的值呢? 下面源码可以看到,IConfigurationRoot会反转添加的顺序,循环遍历,如果找到就返回,所以后面添加的会覆盖前面添加的。

        public string this[string key]
{
get
{  //_providers也就是IConfigurationRoot里面的IList<IConfigurationProvider>
foreach (var provider in _providers.Reverse())
{
string value; if (provider.TryGet(key, out value))
{
return value;
}
}
return null;
}
set
{
if (!_providers.Any())
{
throw new InvalidOperationException(Resources.Error_NoSources);
}
foreach (var provider in _providers)
{
provider.Set(key, value);
}
}
}

对于Json、xml、ini文件,比如

{
"user": {
"address": {
"Provice": "浙江省",
"city": "杭州市"
},
"name": "张三"
}
}

在Data中存储的key为 user:address:Province、user:address:city和user:name。中间以“:”分割,这个“:”是固定只读的,不可以改变的。

三、简单使用

  创建一个WebApi项目,修改Program代码如下:

        public static void Main(string[] args)
{
var configRoot = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())//设置基础路径
.AddJsonFile("a.json")//加载配置
.AddXmlFile("b.xml")
.Build(); var builder = new WebHostBuilder()
.UseConfiguration(configRoot)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.UseStartup<Startup>()
.Build();
builder.Run();
}

  然后当用的时候,只需要注入 IConfiguration ,就能获取所有的配置。

最新文章

  1. 正则表达式抓取文件内容中的http链接地址
  2. jquery基本选择器(.class选择器)
  3. angular $resource模块
  4. MATLAB - 练习程序,直方图均衡化
  5. CBT 简介
  6. js中字符串转换为数字的方法
  7. 使用Linux调用资源库中的Job报错-ERROR: No repository provided, can&#39;t load job.
  8. ERROR 1062 (23000): Duplicate entry &#39;0&#39; for key &#39;PRIMARY&#39;
  9. MLE MAP EM
  10. htaccess URL重写rewrite与重定向redirect(转)
  11. Visual Studio 命中断点时 打印信息
  12. 利用未文档化API:RtlAdjustPrivilege 提权实现自动关机
  13. mysql left join
  14. BZOJ_1800_[Ahoi2009]fly 飞行棋_乱搞
  15. sort注意事项
  16. Java设计模式之七 ----- 享元模式和代理模式
  17. node-rsa
  18. html部分常用标签的含义及作用
  19. Java连接SqlServer2008数据库
  20. 【GISER &amp;&amp; Painter】矢量切片(Vector tile)

热门文章

  1. destoon修改笔记
  2. 【android】6大布局
  3. i2c_drivers个人分析
  4. Wannafly挑战赛21 机器人
  5. vim 查找替换命令
  6. hnust 不爱学习的小w
  7. 【JavaScript】关于 setInterval() 调用函数方法的一次实验
  8. match_parent, wrap_content, 和 fill_parent 区别联系
  9. Django中间件、Auth认证
  10. ie7中position:fixed定位后导致margin:0 auto;无效