翼度科技»论坛 编程开发 .net 查看内容

02-《AspNetCore》-配置

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
Configuration


package说明

Microsoft.Extensions.Configuration.Abstractions:抽象包,一大堆的接口
Microsoft.Extensions.Configuration.Binder:提供一大堆的扩展,比如类型转换
Microsoft.Extensions.Configuration.Json:json实现
Microsoft.Extensions.Configuration.CommandLine:命令行实现
Microsoft.Extensions.Configuration.EnvironmentVariables:环境变量实现
Microsoft.Extensions.Primitives:ChangeToken
基本使用
  1. //创建配置管理器
  2. ConfigurationManager configuration = new ConfigurationManager();
  3. configuration.SetBasePath(Directory.GetCurrentDirectory())
  4.     .AddJsonFile("config.json")//添加json文件
  5.     .AddEnvironmentVariables();//添加系统环境变量
  6. //打印环境变量
  7. Console.WriteLine(configuration.GetSection("path").Value);
  8. //读取josn
  9. var student = configuration.GetSection("student");
  10. Console.WriteLine(student["name"]);
  11. Console.WriteLine(configuration["student:name"]);
  12. //类型转换:需要安装Microsoft.Extensions.Configuration.Binder支持
  13. Console.WriteLine(configuration.GetSection("student:age").Get<int>());
复制代码
自定义

IConfigurationProvider:表示我们的配置的数据源,可以是任意形式具体由自己实现,但是你必须处理成key-value的形式。
IConfigurationSource:用于配置和构建IConfigurationProvider的派生类型
  1. //配置提供器选项:用于提供配置选项
  2. public class IsonConfigurationSource : IConfigurationSource
  3. {
  4.     public string? Url { get; set; }
  5.     public bool ReloadOnChange { get; set; }
  6.     public IsonConfigurationSource()
  7.     {
  8.     }
  9.     public IsonConfigurationSource(string url)
  10.     {
  11.         Url = url;
  12.     }
  13.     public IConfigurationProvider Build(IConfigurationBuilder builder)
  14.     {
  15.         if (Url == null)
  16.         {
  17.             throw new ArgumentNullException(nameof(Url));
  18.         }
  19.         return new IsonConfigurationProvider(this);
  20.     }
  21. }
  22. //配置提供器:配置源逻辑
  23. public class IsonConfigurationProvider : IConfigurationProvider
  24. {
  25.     private ConcurrentDictionary<string, string> values = new ConcurrentDictionary<string, string>();
  26.     private IsonConfigurationSource options;
  27.     private CancellationTokenSource? tokenSource;
  28.     public IsonConfigurationProvider(IsonConfigurationSource options)
  29.     {
  30.         this.options = options;
  31.         //如果需要监听
  32.         if (this.options.ReloadOnChange)
  33.         {
  34.             Watch();
  35.         }
  36.     }
  37.     private void Watch()
  38.     {
  39.         //注册事件
  40.         ChangeToken.OnChange(GetReloadToken, () =>
  41.         {
  42.             Load();
  43.         });
  44.         //模拟更改
  45.         var t = new Thread(() =>
  46.         {
  47.             while (true)
  48.             {
  49.                 var token = tokenSource;
  50.                 tokenSource = null;
  51.                 //每3s之后发生更改
  52.                 Thread.Sleep(3000);
  53.                 //触发事件,触发之前一定要将tokenSource设置成null
  54.                 token!.Cancel();
  55.             }
  56.         });
  57.         t.Start();
  58.     }
  59.     public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath)
  60.     {
  61.         return values.Keys;
  62.     }
  63.     public IChangeToken GetReloadToken()
  64.     {
  65.         lock (this)
  66.         {
  67.             if (tokenSource == null)
  68.             {
  69.                 tokenSource = new CancellationTokenSource();
  70.             }
  71.             return new CancellationChangeToken(tokenSource!.Token);
  72.         }
  73.     }
  74.     public void Load()
  75.     {
  76.         //假设我们从第三方地址获取
  77.         //var client = new HttpClient();
  78.         //var response = client.GetAsync(source.Url).GetAwaiter().GetResult();
  79.         //var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
  80.         values.TryAdd("t1", "1111111");
  81.         values.TryAdd("t2", "2222222");
  82.         Console.WriteLine("ison文件已加载...");
  83.     }
  84.     public void Set(string key, string value)
  85.     {
  86.         values.TryAdd(key, value);
  87.     }
  88.     public bool TryGet(string key, out string value)
  89.     {
  90.         var flag = values.TryGetValue(key, out string? data);
  91.         value = data ?? string.Empty;
  92.         return flag;
  93.     }
  94. }
  95. //扩展IConfigurationBuilder
  96. public static class IsonConfigurationExtensions
  97. {
  98.     public static IConfigurationBuilder AddJsonUrl(this IConfigurationBuilder builder, string url)
  99.     {
  100.         if (builder == null)
  101.         {
  102.             throw new ArgumentNullException(nameof(builder));
  103.         }
  104.         if (string.IsNullOrEmpty(url))
  105.         {
  106.             throw new ArgumentException(nameof(url));
  107.         }
  108.         return builder.Add(new IsonConfigurationSource(url));
  109.     }
  110.     public static IConfigurationBuilder AddJsonUrl(this IConfigurationBuilder builder, Action<IsonConfigurationSource> configure)
  111.     {
  112.         if (builder == null)
  113.         {
  114.             throw new ArgumentNullException(nameof(builder));
  115.         }
  116.         var source = new IsonConfigurationSource();
  117.         configure(source);//执行用户配置
  118.         return builder.Add(source);
  119.     }
复制代码
ChangeToken

ChangeToken:将changeToken生产者和changeToken消费者进行绑定。
IChangeToken:传播已发生更改的通知(也可以自己实现)。可以注册回调在事件发生时执行。
CancellationChangeToken:IChangeToken的一种实现,通过取消令牌来进行通知。
CancellationTokenSource:通知CancellationToken,告知其应被取消,执行回调。
  1. internal class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         var provider = new FileConfigurationProvider();
  6.         //绑定
  7.         provider.Watch();
  8.         new TaskCompletionSource().Task.Wait();
  9.     }
  10. }
  11. /// <summary>
  12. /// 文件配置程序超类
  13. /// </summary>
  14. public class FileConfigurationProvider
  15. {
  16.     private CancellationTokenSource? tokenSource;
  17.     public void Load()
  18.     {
  19.         Console.WriteLine($"[{DateTime.Now}]文件已加载...");
  20.     }
  21.     public void Watch()
  22.     {
  23.         //将changeToken生产者和changeToken消费者进行绑定(订阅)
  24.         ChangeToken.OnChange(GetReloadToken, Load);
  25.         //触发Change事件,通知更新
  26.         var t = new Thread(() =>
  27.         {
  28.             while (true)
  29.             {
  30.                 Thread.Sleep(3000);
  31.                 var t = tokenSource;
  32.                 tokenSource = null;
  33.                 //注意,取消之前一定要将tokenSource设置成null,不然会引发堆栈异常
  34.                 //因为通知了取消,就会获取changeChange,但是你没有设置成null,OnChange认为又发生了取消通知
  35.                 //会一直循环
  36.                 t!.Cancel();//执行回调,发布取消事件。
  37.             }
  38.         });
  39.         t.Start();
  40.     }
  41.     /// <summary>
  42.     /// 更新令牌,通过该令牌可以注册回调,用于执行更新通知。
  43.     /// </summary>
  44.     /// <returns></returns>
  45.     public IChangeToken GetReloadToken()
  46.     {
  47.         lock (this)
  48.         {
  49.             //如果被消费就创建一个新的
  50.             if (tokenSource == null)
  51.             {
  52.                 tokenSource = new CancellationTokenSource();
  53.             }
  54.             return new CancellationChangeToken(tokenSource.Token);
  55.         }
  56.     }
  57. }
复制代码
来源:https://www.cnblogs.com/chaeyeon/archive/2023/02/14/17119507.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具