aspnetcore读取配置【源码分析】


总的逻辑

  1. 继承 IConfigurationSource 这个接口的子类是配置源 ,其中的build方法,创建并返回对应的ConfigurationProvider。
  2. 继承 IConfigurationProvider 这个接口的子类是负责加载/返回配置的,其中的Load方法负责真正的加载配置,TryGet方法获得调用者期望的配置。

再具体的话,大的逻辑是这样的

// 1 添加配置源source ,结果保存在IConfigurationBuilder的成员
// IList Sources { get; } 中
IConfigurationBuilder.Add(IConfigurationSource source)

// 2 加载配置
var configurationRoot = IConfigurationBuilder.Build()
      // 2.1 循环Sources,调用**IConfigurationSource.Build**(IConfigurationBuilder builder) ,
      //该方法返回 xxxxConfigurationSource 对应的 xxxxConfigurationProvider, 并将返回值保存在临时变量Listproviders中
      //2.2 将变量 providers 传递给 ConfigurationRoot 对象 ,**new ConfigurationRoot(providers)**,
      //ConfigurationRoot的构造函数,里面的逻辑是循环 providers ,调用IConfigurationProvider.Load()
      //将配置的具体内容加载到  ** provider 对象中的 IDictionary Data **; 

// 3 获取想要的值
string value1=  configurationRoot["key1"],
//具体实现是倒序循环providers,调用**IConfigurationProvider.TryGet()**获取值;
//为什么是倒序循环,这样如果不同的配置源包含相同的Key,后面添加的会优先后面添加的配置源中的值

举例 ,加载命令行配置

 var args = new string[]
                {
                    "Key1=Value1",
                    "Key2=Value2", 
                };
 // 创建ConfigurationBuilder实例
 var builder = new ConfigurationBuilder();
 //1 添加配置源, 实际上IConfigurationBuilder有很多扩展方法,可以更方便的添加配置
 builder.AddCommandLine(args);
 //2 开始加载配置
 var configurationRoot = builder.Build();
 //3 使用配置
 Console.WriteLine($"Key1:{configurationRoot["Key1"]}");

根据最上面的加载配置的逻辑 ,上面的这个例子的内部核心是这样的

var args = new string[]
                {
                    "Key1=Value1",
                    "Key2=Value2", 
                };
 //设置配置源
 var cmdLineConfig = new CommandLineConfigurationProvider(args);
 //加载配置源 
 cmdLineConfig.Load();
 //使用配置
 Console.WriteLine($"Key1:{cmdLineConfig.Get("Key1")}");