asp.net core 源码学习笔记(配置部分)
- 接口 IConfigurationBuilder
实现类 ConfigurationBuilder
我们都知道 .net Core 下面配置配置 是通过创建 IconfigurationBuilder 对象,下面来看 IconfigurationBuilder 的默认实现
public class ConfigurationBuilder : IConfigurationBuilder
{
public IList<IConfigurationSource> Sources { get; } = new List<IConfigurationSource>();
public IConfigurationBuilder Add(IConfigurationSource source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
Sources.Add(source);
return this;
}
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);
}
}
ConfigurationBuilder 对象中调用的所有Add**扩展方法都是 调用的该类中的Add方法。该方法为 Builder() 函数提供数据源
下面我们再来看Builder() 函数 返回一个ConfigurationRoot 对象(该对象是IConfiguration的实现类)。 通过IConfigurationSource 的Build() 函数 构建IConfigurationProvider 对象 -具体实现1 如下
public class MemoryConfigurationSource : IConfigurationSource
{
public IEnumerable<KeyValuePair<string, string>> InitialData { get; set; }
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new MemoryConfigurationProvider(this);
}
}
同时对于IConfigurationProvider 接口提供了抽象的基础实现ConfigurationProvider 具体实现1 如下
public class MemoryConfigurationProvider : ConfigurationProvider, IEnumerable<KeyValuePair<string, string>>
{
private readonly MemoryConfigurationSource _source;
public MemoryConfigurationProvider(MemoryConfigurationSource source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
_source = source;
if (_source.InitialData != null)
{
foreach (var pair in _source.InitialData)
{
Data.Add(pair.Key, pair.Value);
}
}
}
}
- 基类实现
public abstract class ConfigurationProvider : IConfigurationProvider
{
private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();
protected ConfigurationProvider()
{
Data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
protected IDictionary<string, string> Data { get; set; }
public virtual bool TryGet(string key, out string value)
=> Data.TryGetValue(key, out value);
public virtual void Set(string key, string value)
=> Data[key] = value;
public virtual void Load()
{ }
public IChangeToken GetReloadToken()
{
return _reloadToken;
}
protected void OnReload()
{
var previousToken = Interlocked.Exchange(ref _reloadToken, new ConfigurationReloadToken());
previousToken.OnReload();
}
public override string ToString() => $"{GetType().Name}";
}
}
最后返回的ConfigurationRoot 就是我们常用的IConfiguration
至于我们用的IConfigurationSection 实际上就是对ConfigurationRoot的封装