02-《AspNetCore》-Configuration

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

基本使用

//创建配置管理器
ConfigurationManager configuration = new ConfigurationManager();
configuration.SetBasePath(Directory.GetCurrentDirectory())
 .AddJsonFile("config.json")//添加json文件
 .AddEnvironmentVariables();//添加系统环境变量
//打印环境变量
Console.WriteLine(configuration.GetSection("path").Value);
//读取josn
var student = configuration.GetSection("student");
Console.WriteLine(student["name"]);
Console.WriteLine(configuration["student:name"]);
//类型转换:需要安装Microsoft.Extensions.Configuration.Binder支持
Console.WriteLine(configuration.GetSection("student:age").Get<int>());

自定义

IConfigurationProvider:表示我们的配置的数据源,可以是任意形式具体由自己实现,但是你必须处理成key-value的形式。

IConfigurationSource:用于配置和构建IConfigurationProvider的派生类型

//配置提供器选项:用于提供配置选项
public class IsonConfigurationSource : IConfigurationSource
{
 public string? Url { get; set; }
 public bool ReloadOnChange { get; set; }
 public IsonConfigurationSource()
 {
 }
 public IsonConfigurationSource(string url)
 {
 Url = url;
 }
 public IConfigurationProvider Build(IConfigurationBuilder builder)
 {
 if (Url == null)
 {
 throw new ArgumentNullException(nameof(Url));
 }
 return new IsonConfigurationProvider(this);
 }
}
//配置提供器:配置源逻辑
public class IsonConfigurationProvider : IConfigurationProvider
{
 private ConcurrentDictionary<string, string> values = new ConcurrentDictionary<string, string>();
 private IsonConfigurationSource options;
 private CancellationTokenSource? tokenSource;
 public IsonConfigurationProvider(IsonConfigurationSource options)
 {
 this.options = options;
 //如果需要监听
 if (this.options.ReloadOnChange)
 {
 Watch();
 }
 }
 private void Watch()
 {
 //注册事件
 ChangeToken.OnChange(GetReloadToken, () =>
 {
 Load();
 });
 //模拟更改
 var t = new Thread(() =>
 {
 while (true)
 {
 var token = tokenSource;
 tokenSource = null;
 //每3s之后发生更改
 Thread.Sleep(3000);
 //触发事件,触发之前一定要将tokenSource设置成null
 token!.Cancel();
 }
 });
 t.Start();
 }
 public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath)
 {
 return values.Keys;
 }
 public IChangeToken GetReloadToken()
 {
 lock (this)
 {
 if (tokenSource == null)
 {
 tokenSource = new CancellationTokenSource();
 }
 return new CancellationChangeToken(tokenSource!.Token);
 }
 }
 public void Load()
 {
 //假设我们从第三方地址获取
 //var client = new HttpClient();
 //var response = client.GetAsync(source.Url).GetAwaiter().GetResult();
 //var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
 values.TryAdd("t1", "1111111");
 values.TryAdd("t2", "2222222");
 Console.WriteLine("ison文件已加载...");
 }
 public void Set(string key, string value)
 {
 values.TryAdd(key, value);
 }
 public bool TryGet(string key, out string value)
 {
 var flag = values.TryGetValue(key, out string? data);
 value = data ?? string.Empty;
 return flag;
 }
}
//扩展IConfigurationBuilder
public static class IsonConfigurationExtensions
{
 public static IConfigurationBuilder AddJsonUrl(this IConfigurationBuilder builder, string url)
 {
 if (builder == null)
 {
 throw new ArgumentNullException(nameof(builder));
 }
 if (string.IsNullOrEmpty(url))
 {
 throw new ArgumentException(nameof(url));
 }
 return builder.Add(new IsonConfigurationSource(url));
 }
 public static IConfigurationBuilder AddJsonUrl(this IConfigurationBuilder builder, Action<IsonConfigurationSource> configure)
 {
 if (builder == null)
 {
 throw new ArgumentNullException(nameof(builder));
 }
 var source = new IsonConfigurationSource();
 configure(source);//执行用户配置
 return builder.Add(source);
 }

ChangeToken

ChangeToken:将changeToken生产者和changeToken消费者进行绑定。

IChangeToken:传播已发生更改的通知(也可以自己实现)。可以注册回调在事件发生时执行。

CancellationChangeToken:IChangeToken的一种实现,通过取消令牌来进行通知。

CancellationTokenSource:通知CancellationToken,告知其应被取消,执行回调。

internal class Program
{
 static void Main(string[] args)
 {
 var provider = new FileConfigurationProvider();
 //绑定
 provider.Watch();
 new TaskCompletionSource().Task.Wait();
 }
}
/// <summary>
/// 文件配置程序超类
/// </summary>
public class FileConfigurationProvider
{
 private CancellationTokenSource? tokenSource;
 public void Load()
 {
 Console.WriteLine($"[{DateTime.Now}]文件已加载...");
 }
 public void Watch()
 {
 //将changeToken生产者和changeToken消费者进行绑定(订阅)
 ChangeToken.OnChange(GetReloadToken, Load);
 //触发Change事件,通知更新
 var t = new Thread(() =>
 {
 while (true)
 {
 Thread.Sleep(3000);
 var t = tokenSource;
 tokenSource = null;
 //注意,取消之前一定要将tokenSource设置成null,不然会引发堆栈异常
 //因为通知了取消,就会获取changeChange,但是你没有设置成null,OnChange认为又发生了取消通知
 //会一直循环
 t!.Cancel();//执行回调,发布取消事件。
 }
 });
 t.Start();
 }
 /// <summary>
 /// 更新令牌,通过该令牌可以注册回调,用于执行更新通知。
 /// </summary>
 /// <returns></returns>
 public IChangeToken GetReloadToken()
 {
 lock (this)
 {
 //如果被消费就创建一个新的
 if (tokenSource == null)
 {
 tokenSource = new CancellationTokenSource();
 }
 return new CancellationChangeToken(tokenSource.Token);
 }
 }
}
作者:花间岛原文地址:https://www.cnblogs.com/chaeyeon/p/17119507.html

%s 个评论

要回复文章请先登录注册