ConfigurationBuilder 读取文件流程
1 AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); 最后 ConfigurationBuilder 添加addjson的信息,存到集合 IList<IConfigurationSource>里
2 build()
2.1 IConfigurationProvider.build() 注册 ChangeToken.OnChange 添加 一个监控和回调委托 ,返回注册 token
2.2 new ConfigurationRoot(providers); 读取配置文件
3 当监控的配置文件改动时,ChangeToken.OnChange 添加 一个监控和回调委托,
监控委托最后在 PhysicalFilesWatcher 类里 通过注册 FileSystemWatcher 里的事件 来改变来启动并监控更改,然后通过流读取数据。这里利用递归,读取配置文件文件,然后重新注册IChangeToken,更改标识符
将ChangeToken.OnChange 事件添加到 List<IDisposable>集合里
new ConfigurationRoot(providers);
这里利用递归,
最后读取出来
一个重载
20240514 var build = new ConfigurationBuilder(); var res= build.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json",true,true) .Build(); var res2=res["WXFlowAddress:FlowPreview"]; ConfigurationBuilder 添加 json文件 创建jsonconfigsource 委托 添加到IConfigurationSource list集合里 代码 return builder.AddJsonFile(s => { s.FileProvider = provider; s.Path = path; s.Optional = optional; s.ReloadOnChange = reloadOnChange; s.ResolveFileProvider(); }); public static IConfigurationBuilder Add<TSource>(this IConfigurationBuilder builder, Action<TSource>? configureSource) where TSource : IConfigurationSource, new() { var source = new TSource(); configureSource?.Invoke(source); return builder.Add(source); } IConfigurationRoot Build() { var providers = new List<IConfigurationProvider>(); foreach (IConfigurationSource source in _sources) { IConfigurationProvider provider = source.Build(this); providers.Add(provider); } return new ConfigurationRoot(providers); 然后source.Build(this); ,这里就是 List<IConfigurationSource> 查询便利里面的数据 change.token 注册两个方法 这里实现了 热更新,。第一个方法里 创建 changeToken用来判断是否 更改了,并返回,初始为false。 在 PhysicalFileProvider 并启动了 监控类 FileSystemWatcher 的监控启动等一系类操作 _changeTokenRegistration = ChangeToken.OnChange( () => Source.FileProvider.Watch(Source.Path!), () => { Thread.Sleep(Source.ReloadDelay); Load(reload: true); }); 然后 new ConfigurationRoot(providers); 这里 用Load方法加载流读取了 读取了json文件,并更改 changetoken里的状态 然后重新注册一个 token状态等待下次更改, 在更改文件后 会触发 更改调用,这里痛哦过委托来执行前面的步骤,并重新注册,类似递归,这里是changetoken的代码了 public ChangeTokenRegistration(Func<IChangeToken?> changeTokenProducer, Action<TState> changeTokenConsumer, TState state) { _changeTokenProducer = changeTokenProducer; _changeTokenConsumer = changeTokenConsumer; _state = state; IChangeToken? token = changeTokenProducer(); RegisterChangeTokenCallback(token); } private void OnChangeTokenFired() { // The order here is important. We need to take the token and then apply our changes BEFORE // registering. This prevents us from possible having two change updates to process concurrently. // // If the token changes after we take the token, then we'll process the update immediately upon // registering the callback. //这里时 执行 Source.FileProvider.Watch(Source.Path!) 读文文件 IChangeToken? token = _changeTokenProducer(); try { //在callback()里传入委托 () => //{ // Thread.Sleep(Source.ReloadDelay); // Load(reload: true); //}); _changeTokenConsumer(_state); } finally { // We always want to ensure the callback is registered RegisterChangeTokenCallback(token); } } private void RegisterChangeTokenCallback(IChangeToken? token) { if (token is null) { return; } IDisposable registraton = token.RegisterChangeCallback(s => ((ChangeTokenRegistration<TState>?)s)!.OnChangeTokenFired(), this); if (token.HasChanged && token.ActiveChangeCallbacks) { registraton?.Dispose(); return; } SetDisposable(registraton); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)