Configuration 視頻講解 package說明 Microsoft.Extensions.Configuration.Abstractions:抽象包,一大堆的介面 Microsoft.Extensions.Configuration.Binder:提供一大堆的擴展,比如類型轉換 Micr ...
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);
}
}
}