asp.net core配置文件加载过程的深入了解

2019-05-25 09:17:56刘景俊

其中一个方法包含了 4 个参数,代码如下

 public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange)
  {
   if (builder == null)
   {
    throw new ArgumentNullException(nameof(builder));
   }
   if (string.IsNullOrEmpty(path))
   {
    throw new ArgumentException(Resources.Error_InvalidFilePath, nameof(path));
   }

   return builder.AddJsonFile(s =>
   {
    s.FileProvider = provider;
    s.Path = path;
    s.Optional = optional;
    s.ReloadOnChange = reloadOnChange;
    s.ResolveFileProvider();
   });
  }

在此方法中,有一个参数 bool reloadOnChange,从参数描述可知,该值指示在文件变动的时候是否重新加载,默认值为:false;一般在手动加载配置文件,即调用 AddJsonFile 方法时,建议将该参数值设置为 true。

那么 .netcore 是如果通过该参数 reloadOnChange 是来监控文件变动,以及何时进行重新加载的操作呢,看下面代码

  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);
  }

在我们执行 .Build 方法的时候,方法内部最后一行代码给我们利用 AddJsonFile 方法的参数创建并返回了一个 ConfigurationRoot 对象

在 ConfigurationRoot 的构造方法中

  public ConfigurationRoot(IList<IConfigurationProvider> providers)
  {
   if (providers == null)
   {
    throw new ArgumentNullException(nameof(providers));
   }

   _providers = providers;
   foreach (var p in providers)
   {
    p.Load();
    ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged());
   }
  }

我们看到,方法内部一次读取了通过 AddJsonFile 方法加入的配置文件,并为每个配置文件单独分配了一个监听器 ChangeToken,并绑定当前文件读取对象 IConfigurationProvider.GetReloadToken 方法到监听器中

当文件产生变动的时候,监听器会收到一个通知,同时,对该文件执行原子操作

 private void RaiseChanged()
  {
   var previousToken = Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());
   previousToken.OnReload();
  }

由于 AddJsonFile 方法内部使用了 JsonConfigurationSource ,而 Build 的重载方法构造了一个 JsonConfigurationProvider 读取对象,查看代码

  public override IConfigurationProvider Build(IConfigurationBuilder builder)
  {
   EnsureDefaults(builder);
   return new JsonConfigurationProvider(this);
  }

在 JsonConfigurationProvider 继承自 FileConfigurationProvider 类,该类位于程序集