Fork me on GitHub

Asp.net Core Configuration

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的封装

详细源码见 https://github.com/aspnet/Extensions

posted @ 2019-03-01 15:32  航海世纪  阅读(446)  评论(0)    收藏  举报