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);
  }
复制代码

 

posted @   孤海飞雁  阅读(169)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示