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 类,该类位于程序集 Microsoft.Extensions.Configuration.Json.dll 内
在 FileConfigurationProvider 的构造方法中实现了监听器重新加载配置文件的过程
public FileConfigurationProvider(FileConfigurationSource source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } Source = source; if (Source.ReloadOnChange && Source.FileProvider != null) { ChangeToken.OnChange( () => Source.FileProvider.Watch(Source.Path), () => { Thread.Sleep(Source.ReloadDelay); Load(reload: true); }); } }
值得注意的是,该监听器不是在得到文件变动通知后第一时间去重新加载配置文件,方法内部可以看到,这里有一个 Thread.Sleep(Source.ReloadDelay) ,而 ReloadDelay 的默认值为:250ms,该属性的描述为
获取或者设置重新加载将等待的毫秒数, 然后调用 "Load" 方法。 这有助于避免在完全写入文件之前触发重新加载。默认值为250
让人欣慰的是,我们可以自定义该值,如果业务对文件变动需求不是特别迫切,您可以将该值设置为一个很大的时间,通常情况下,我们不建议那么做
结语
以上就是 asp.netcore 中配置文件加载的内部执行过程,从中我们认识到,默认配置文件是如何加载,并将默认配置文件如何注入到系统中的,还学习到了如果在不同的环境下,选择加载自定义配置文件的过程;但配置文件变动的时候,系统内部又是如何去把配置文件重新加载到内存中去的。
您可能感兴趣的文章: