ConfigurationBuilder里添加了一个JsonConfigurationSource对象。
最后,执行ConfigurationBuilder的Build方法,就可以得到保存配置信息的Configuration对象。
总结例子中的代码,获取配置信息的操作其实就分为两步:
1.生成Configuration对象
2.按键值从Configuration对象中获取信息
生成Configuration对象的步骤至少要有三个基础环节。
1.生成ConfigurationBuilder对象
2.添加ConfigurationSource对象
3.创建Configuration对象
查看创建Configuration对象的代码,会发现内部利用的其实是ConfigurationSource中创建的ConfigurationProvider对象。
public IConfigurationRoot Build()
{
var providers = new List<IConfigurationProvider>();
foreach (var source in Sources)
{
var provider = source.Build(this);
providers.Add(provider);
}
return new ConfigurationRoot(providers);
}
再看IConfiguratonSource接口,也只有一个Build方法。
public interface IConfigurationSource
{
IConfigurationProvider Build(IConfigurationBuilder builder);
}
最终创建的Configuration对象,即ConfigurationRoot中包含了所有的ConfigurationProvider,说明配置信息都由这些ConfigurationProvider所提供。
跟踪至ConfigurationRoot类型的构造方法,果然在其生成对象时,对所有ConfigurationProvider进行了加载操作。
public ConfigurationRoot(IList<IConfigurationProvider> providers)
{
...
_providers = providers;
foreach (var p in providers)
{
p.Load();
ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged());
}
}
比如JsonConfigurationProvider中:
public override void Load(Stream stream)
{
try
{
Data = JsonConfigurationFileParser.Parse(stream);
}
...
}
通过JSON解析器,将JSON文件的配置信息读取至ConfigurationProvider的Data属性中。这个属性即是用于保存所有配置信息。
/// <summary>
/// The configuration key value pairs for this provider.
/// </summary>
protected IDictionary<string, string> Data { get; set; }
有了ConfigurationRoot对象后,获取配置信息的操作就很简单了。遍历各个ConfigurationProvider,从中获取第一个匹配键值的数据。
public string this[string key]
{
get
{
foreach (var provider in _providers.Reverse())
{
string value;
if (provider.TryGet(key, out value))
{
return value;
}
}
return null;
}
...
}
ConfigurationProvider对象从Data属性获取配置的值。
public virtual bool TryGet(string key, out string value) => Data.TryGetValue(key, out value);








