- A+
所属分类:.NET技术
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); } } }