.net core 源码分析(6) 启动过程-InitializeAppConfiguration

InitializeAppConfiguration 方法用于初始化应用程序的配置。

private void InitializeAppConfiguration()
{
    // 创建一个配置构建器,注意AddConfiguration(_hostConfiguration)
    IConfigurationBuilder configBuilder = new ConfigurationBuilder()
     //添加到共享属性  public IDictionary<string, object> Properties 中
        .SetBasePath(_hostingEnvironment!.ContentRootPath)
        .AddConfiguration(_hostConfiguration!, shouldDisposeConfiguration: true);

  
    foreach (Action<HostBuilderContext, IConfigurationBuilder> buildAction in _configureAppConfigActions)
    {
        buildAction(_hostBuilderContext!, configBuilder);
    }

    // 私有属性赋值_appConfiguration ,注意和_hostConfigration区别 
    _appConfiguration = configBuilder.Build();

    // 使用新的配置更新 HostBuilderContext,这里_hostBuilderContext.Configuration被覆盖了,覆盖之前指向_hostConfiguration
    _hostBuilderContext!.Configuration = _appConfiguration;
}

在讲解整个过程之前有必要回顾一下Configuration模块中几个核心类型之间的关系。

 

ConfigurationBuilder.AddSource方法可以添加不同的配置源。  ConfigurationBuilder.AddConfiguration(_hostConfiguration) 其实就是把 _hostConfiguration 转换成为ChainedConfigurationSource类型的配置源。这样就实现了把_hostConfiguration的配置信息给合并到_appConfiguration中,所以即便_hostBuilderContext.Configuration被覆盖,但是还是可以通过新的对象访问到原有对象中的配置信息的。

 /// <summary>
    /// 将一个现有的 <see cref="IConfiguration"/> 实例添加到指定的
    /// <paramref name="configurationBuilder"/> 中,并可以选择在配置提供者被释放时自动释放配置对象。
    /// </summary>
    /// <param name="configurationBuilder">要添加配置的 <see cref="IConfigurationBuilder"/></param>
    /// <param name="config">要添加的 <see cref="IConfiguration"/> 实例。</param>
    /// <param name="shouldDisposeConfiguration">指示在配置提供者被释放时,是否自动释放配置对象。</param>
    /// <returns>返回已修改的 <see cref="IConfigurationBuilder"/> 实例。</returns>
    public static IConfigurationBuilder AddConfiguration(this IConfigurationBuilder configurationBuilder, IConfiguration config, bool shouldDisposeConfiguration)
    {
        // 验证传入的参数不为 null
        ThrowHelper.ThrowIfNull(configurationBuilder);
        ThrowHelper.ThrowIfNull(config);

        // 将配置添加到构建器中,并指定是否需要在释放时释放配置对象
        configurationBuilder.Add(new ChainedConfigurationSource
        {
            Configuration = config,
            ShouldDisposeConfiguration = shouldDisposeConfiguration,
        });

        // 返回已修改的构建器
        return configurationBuilder;
    }

最后附上ConfiguratonBuilder的源码

public class ConfigurationBuilder : IConfigurationBuilder
{
    private readonly List<IConfigurationSource> _sources = new();

    /// <summary>
    /// 返回用于获取配置值的配置源集合。
    /// </summary>
    public IList<IConfigurationSource> Sources => _sources;

    /// <summary>
    /// 获取一个键/值集合
    ///共享数据。
    /// </summary>
    public IDictionary<string, object> Properties { get; } = new Dictionary<string, object>();

    /// <summary>
    /// 添加一个新的配置源。
    /// </summary>
    /// <param name="source">要添加的配置源。</param>
    /// <returns>返回当前的实例 <see cref="IConfigurationBuilder"/></returns>
    public IConfigurationBuilder Add(IConfigurationSource source)
    {
        ThrowHelper.ThrowIfNull(source);

        _sources.Add(source);
        return this;
    }

    public IConfigurationRoot Build()
    {
        var providers = new List<IConfigurationProvider>();
        foreach (IConfigurationSource source in _sources)
        {
            IConfigurationProvider provider = source.Build(this);
            providers.Add(provider);
        }
        return new ConfigurationRoot(providers);
    }
}

 

 

.net core 源码分析

posted @ 2024-08-21 14:53  Hi同学  阅读(5)  评论(0编辑  收藏  举报