.NET 中配置從xml轉向json方法示例詳解
目錄
- 一、配置概述
- 二、配置初識
- 三、選項模式
- 四、選項依賴注入
- 五、其它配置
- 六、托管模式
一、配置概述
在.net framework平臺中我們常見的也是最熟悉的就是.config
文件作為配置,控制臺桌面程序是App.config
,Web就是web.config
,里面的配置格式為xml格式。
在xml里面有系統生成的配置項,也有我們自己添加的一些配置,最常用的就是appSettings節點,用來配置數據庫連接和參數。
使用的話就引用包System.Configuration.ConfigurationManager
之后取里面的配置信息:
System.Configuration.ConfigurationManager.AppSettings["ConnectionString"]
隨著技術的發展這種配置方式顯得冗余復雜,如果配置項太多層級關系參數表達凌亂,在.net core開始也將配置的格式默認成了json格式,包括現在很多的其它配置也是支持的,比如java中常用的yaml格式,為什么能支持這么多讀取源和格式,其實質在于配置提供程序。
目前.NET 中的配置是使用一個或多個配置提供程序執行的。 配置提供程序使用各種配置源從鍵值對讀取配置數據,這些配置程序稍后我們會看到,讀取的配置源可以是如下這些:
- 設置文件,appsettings.json
- 環境變量
- Azure Key Vault
- Azure 應用配置
- 命令行參數
- 已安裝或已創建的自定義提供程序
- 目錄文件
- 內存中的 .NET 對象
- 第三方提供程序
二、配置初識
IConfiguration 接口是所有配置源的單個表示形式,給定一個或多個配置源,IConfiguration 類型提供配置數據的統一視圖。
上圖我們可能沒有直觀的感受,現在寫一個例子來看看
(1). 新建控制臺應用程序:創建控制臺使用的是.net 6.0 框架,vs 2022。
安裝 Microsoft.Extensions.Configuration.Json NuGet 包,該包提供json配置文件讀取。
Install-Package Microsoft.Extensions.Configuration.Json
(2). 添加appsettings.json 文件
{ "person": { "name": "XSpringSun", "age": 18 }}
(3). 使用json提供程序讀取json配置new一個ConfigurationBuilder,添加json配置,AddJsonFile
是在包中的IConfigurationBuilder擴展方法,其它配置提供程序也是用這種擴展方法實現。
static void Main(string[] args){ IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); Console.WriteLine(configuration["person:name"]); Console.WriteLine(configuration["person:age"]); Console.WriteLine("Hello, World!"); Console.ReadLine();}
可以看到已經取到json配置文件中的值了,配置值可以包含分層數據。 分層對象使用配置鍵中的 : 分隔符表示。在下面的調試對象中我們可以看到實際configuration的Providers 提供程序數組有一個值,就是我們的JsonConfigurationProvider,并且JsonConfigurationProvider里面已經讀取了json的數據存儲在Data數組中。
對于如上幾行代碼干了什么呢:
- 將 ConfigurationBuilder 實例化(new ConfigurationBuilder)。
- 添加 "appsettings.json" 文件,由 JSON 配置提供程序識別(AddJsonFile("appsettings.json"))。
- 使用 configuration 實例獲取所需的配置
三、選項模式
這樣已經實現json進行配置讀取,但是取值的方式似乎和以前沒什么太大變法,所以.net提供了選項模式,選項模式就是使用類來提供對相關設置組的強類型訪問。
我們創建一個Config
類用來轉換json:
namespace ConfigDemo{ public class Config {public Person? person { get; set; } } public class Person {public string? name { get; set; }public int age { get; set; } }}
綁定配置
IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); Config options = new Config(); ConfigurationBinder.Bind(configuration, options); Person person = configuration.GetSection("person").Get<Person>(); Console.WriteLine(options.person.name); Console.WriteLine(options.person.age); Console.WriteLine("-----------GetSection獲取-------------"); Console.WriteLine(person.name); Console.WriteLine(person.age);
用了兩種方式獲取配置,第一種使用ConfigurationBinder.Bind()
將整個配置綁定到對象Config
上,另外一種是使用IConfiguration的GetSection().Get<T>()
并返回指定的類型。兩種方式都可以使用,看實際需求和用途。
四、選項依賴注入
在控制臺程序中我們引用DI注入包,然后演示下如何進行配置的注入。關于DI和IOC不清楚的看我上篇文章.net 溫故知新:【7】IOC控制反轉,DI依賴注入
- 新建一個測試類TestOptionDI
public class TestOptionDI {private readonly IOptionsSnapshot<Config> _options;public TestOptionDI(IOptionsSnapshot<Config> options){ _options = options;}public void Test(){ Console.WriteLine("DI測試輸出:"); Console.WriteLine($"姓名:{_options.Value.person.name}"); Console.WriteLine($"年齡:{_options.Value.person.age}");} }
在測試類中我們使用IOptionsSnapshot<T>
接口作為依賴注入,還有其它不同定義的接口用來配置注入,關于選項接口:。
不同接口可以配合讀取配置的不同方式起作用,IOptionsSnapshot接口可以在配置文件改變后不同作用域進行刷新配置。接著我們修改main方法,引入DI,并將AddJsonFile
方法的參數reloadOnChange設置為true,optional參數是否驗證文件存在,建議開發時都設置為true,這樣如果文件有問題會進行報錯。
注入配置這句services.AddOptions().Configure<Config>(e=>configuration.Bind(e))
是關鍵,通過容器調用AddOptions
方法注冊,然后Configure
方法里面是一個委托方法,該委托的作用就是將配置的信息綁定到Config類型的參數e上。注冊到容器的泛型選項接口,這樣在TestOptionDI類構造函數注入就能注入IOptionsSnapshot了,這里有點繞。
static void Main(string[] args){ IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json",optional:true,reloadOnChange:true).Build(); //IServiceCollection 服務 ServiceCollection services = new ServiceCollection(); //注入配置 services.AddOptions().Configure<Config>(e=>configuration.Bind(e)); //注入TestOptionDI services.AddScoped<TestOptionDI>(); using (var provider = services.BuildServiceProvider()) {//獲取服務var testOption = provider.GetRequiredService<TestOptionDI>();testOption.Test(); } Console.ReadLine();}
為了測試IOptionsSnapshot接口在不同作用域會刷新配置,我們修改下main方法,用一個while循環在ReadLine時修改json文件值,不同的Scope里進行打印。
using (var provider = services.BuildServiceProvider()) {while (true){ using (var scope = provider.CreateScope()) {//獲取服務var testOption = scope.ServiceProvider.GetRequiredService<TestOptionDI>();testOption.Test(); } Console.ReadLine();} }
這個功能在web中使用很方便,因為框架的一次請求就是一個作用域,所以我們修改了配置,下次請求就能生效了,而不用重啟服務。
五、其它配置
如最開始所說,不僅能配置json文件,由于各種提供程序,還可以配置其它的,但是根據配置的順序會進行覆蓋。我們只添加一個環境變量配置演示下:
首先添加提供程序包:Install-Package Microsoft.Extensions.Configuration.EnvironmentVariables
。
然后添加環境變量配置代碼AddEnvironmentVariables()
:
IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json",optional:true,reloadOnChange:true).AddEnvironmentVariables().Build();
在VS中配置臨時環境變量
這里有個扁平化配置,就是表示層級用冒號person:age
六、托管模式
對于web項目我們沒有進行這么多操作它是怎么配置的呢,其實框架已經自動幫我們做了,其它非web項目也可以使用這種托管模式,在Microsoft.Extensions.Hosting 包中,只需要使用簡單的代碼就能配置好。
IHost host = Host.CreateDefaultBuilder(args).Build();await host.RunAsync();
其加載配置的優先級:
通過分析我們對整個配置如何運行的機制有了一個大體的了解,如果想詳細了解托管模式的還是建議看官方文檔:.NET配置
以上就是.NET 中配置從xml轉向json方法示例詳解的詳細內容,更多關于.NET配置xml轉向json的資料請關注其它相關文章!