一.配置框架的核心類庫#
首先我們使用.NET Core的配置框架需要安裝額外的NuGet擴展包,下面是列舉最常用的幾個擴展包以及所對應的配置功能
NuGet PackageDescriptionMicrosoft.Extensions.Configuration配置框架的核心庫,提供有關Configuration的抽象類和實現類Microsoft.Extensions.Configuration.CommandLine能夠使用命令參數進行配置Microsoft.Extensions.Configuration.EnvironmentVariables能夠使用環境變量進行配置Microsoft.Extensions.Configuration.Json能夠使用json文件進行配置Microsoft.Extensions.Configuration.Xml能夠使用xml文件進行配置Microsoft.Extensions.Configuration.Ini能夠使用Ini文件進行配置Microsoft.Extensions.Configuration.Binder支持強類型對象綁定配置
二.一個Configuration的構建#
下面我們在控制檯使用內存存儲配置信息並且完成一個Configuration的構造,代碼如下:
<code>Copy
static
void
Main
(string
[] args) { IConfigurationBuilder builder =new
ConfigurationBuilder(); builder.AddInMemoryCollection(new
Dictionary<string
,string
>() { {"Name"
,"Foo"
}, {"Sex"
,"Male"
}, {"Job"
,"Student"
}, }); IConfiguration configuration = builder.Build();foreach
(var
itemin
configuration.GetChildren()) { Console.WriteLine($"
{item.Key}
:{item.Value}
"); } Console.ReadLine(); } /<code>
輸出結果:
<code>CopyJob
:Student
Name
:Foo
Sex
:Male
/<code>
那麼我們可以看到一個configuration的構建的步驟:
- 定義ConfigurationBuilder
- 為ConfigurationBuilder添加ConfigurationSource
- 通過ConfigurationBuilder的Build方法完成構建
三.通過命令行配置#
首先我們在項目的調試的應用程序參數加入命令行參數:
代碼修改如下:
<code>Copy builder.AddInMemoryCollection(new
Dictionary<string
,string
>() { {"Name"
,"Foo"
}, {"Sex"
,"Male"
}, {"Job"
,"Student"
}, }) .AddCommandLine(args); /<code>
輸出:
<code>CopyAge
:23
Job
:Student
Name
:Ryzen
Sex
:Male
/<code>
同時我們在輸出結果看到,key為Name的value變化了,證明當不同配置源存在相同Key時,會被後添加的配置源覆蓋其value
四.通過環境變量配置#
下面的環節由於出於演示效果,通過WPF程序來演示,首先創建好一個wpf項目,界面如下:
我們在項目的調試的環境變量添加幾個參數:
在App.cs中構建一個靜態屬性IConfiguration,代碼如下:
<code>Copypublic
partial
class
App
:Application
{public
static
IConfiguration MyConfigration =>new
ConfigurationBuilder() .AddEnvironmentVariables() } /<code>
MainWindow.cs:
<code>Copypublic
partial
class
MainWindow
:Window
{public
MainWindow
() { InitializeComponent(); }private
void
Button_Click
(object
sender, RoutedEventArgs e) { LoadEnv(); }private
void
LoadEnv
() {string
envString =string
.Empty;this
.textbox_env.Text =$"Env__IsProduction:
{App.MyConfigration.GetSection(
"Env"
)["IsProduction"
]}"+"\n"
;this
.textbox_env.Text +=$"Env__IsDevelopment:
{App.MyConfigration.GetSection(
"Env"
)["IsDevelopment"
] }"+"\n"
;this
.textbox_env.Text +=$"Class__Team__Group:
{App.MyConfigration.GetSection(
"Class:Team"
)["Group"
]}"; } } /<code>
實現效果:
在注入環境變量時,還支持去前綴過濾篩選注入,修改App.cs:
<code>Copypublic
partial
class
App
:Application
{public
static
IConfiguration MyConfigration =>new
ConfigurationBuilder() .AddEnvironmentVariables("Env:"
) } /<code>
修改MainWindow.cs:
<code>Copy
private
void
LoadEnv
() {string
envString =string
.Empty;this
.textbox_env.Text =$"Env__IsProduction:
{App.MyConfigration.GetSection(
"Env"
)["IsProduction"
]}"+"\n"
;this
.textbox_env.Text +=$"Env__IsDevelopment:
{App.MyConfigration.GetSection(
"Env"
)["IsDevelopment"
] }"+"\n"
;this
.textbox_env.Text +=$"Class__Team__Group:
{App.MyConfigration.GetSection(
"Class:Team"
)["Group"
]}" +"\n"
;this
.textbox_env.Text +=$"IsProduction:
{App.MyConfigration[
"IsProduction"
]}"; } /<code>
效果如下:
我們會發現,之前的環境變量都被過濾了,只能讀取被過濾前綴後的環境變量
配置環境變量時的注意點:
- 和json等文件不同,環境變量的Key是以__雙下劃線為分層鍵,而不是:冒號
- 分層讀取的時候是以冒號:來進行讀取
五.通過文件來配置#
1.創建和讀取配置文件#
首先我們新建一個Configurations文件夾,然後再該文件夾創建三個配置文件
appsetting.json:
<code>Copy{
"Human":
{
"Name":
"Foo"
,
"Body":
{
"Height":
190
,
"Weight":
170
},
"Sex":
"Male"
,
"Age":
24
,
"IsStudent":
true
}
}
/<code>
appsetting.xml:
<code>Copy<
Configuration
><
DbServers
><
SqlSever
>12SqlSever
><
MySql
>11MySql
>DbServers
>Configuration
> /<code>
appsetting.ini:
<code>Copy[Ini] IniKey1=IniValue1 IniKey2=IniValue2 /<code>
在App.cs分別注入這三個文件:
<code>Copypublic
partial
class
App
:Application
{public
static
IConfiguration MyConfigration =>new
ConfigurationBuilder() .AddEnvironmentVariables("Env:"
) .AddJsonFile(@"Configurations\appsetting.json"
,false
,true
) .AddXmlFile(@"Configurations\appsetting.xml"
,false
,true
) .AddIniFile(@"Configurations\appsetting.Ini"
) .Build(); } /<code>
修改MainWindow代碼,分別讀取這三個文件:
<code>Copyprivate
void
Button_Click
(object
sender, RoutedEventArgs e) { LoadEnv(); LoadJson(); LoadXML(); LoadIni(); }private
void
LoadJson
() {var
jsonString =string
.Empty;foreach
(var
itemin
App.MyConfigration.GetSection("Human"
).GetChildren()) {if
(item.Key.Contains("Body"
)) {foreach
(var
bodyin
item.GetChildren()) { jsonString +=$"
{body.Key}
:{body.Value}
\n"; } }else
{ jsonString +=$"
{item.Key}
:{item.Value}
\n"; } }this
.textbox_json.Text = jsonString; }private
void
LoadXML
() {var
xmlString =string
.Empty;foreach
(var
itemin
App.MyConfigration.GetSection("DbServers"
).GetChildren()) { xmlString +=$"
{item.Key}
:{item.Value}
\n"; }this
.textbox_xml.Text = xmlString; }private
void
LoadIni
() {var
iniString =string
.Empty;foreach
(var
itemin
App.MyConfigration.GetSection("Ini"
).GetChildren()) { iniString +=$"
{item.Key}
:{item.Value}
\n"; }this
.textbox_ini.Text = iniString; } /<code>
效果如下:
2.支持文件變更時重新讀取和設置變更監視#
以json文件為例,我們在App.cs注入json文件時調用此方法
<code>CopyAddJsonFile(@"Configurations\appsetting.json",
false
,
true
)
/<code>
該方法有是一個重載方法,最常用的是三個參數的重載方法,下面是三個參數的作用
- path:文件路徑
- optional:默認為false,當找不到該文件路徑會報錯,true則不報錯
- reloadOnChange:默認為false,當為true時支持配置文件變更後重新讀取
首先,我們為appsetting.json文件設置屬性,複製到輸出目錄=>如果較新則複製,生成操作=>內容
然後我們通過一個內置的靜態方法監控文件變更,修改MainWindows.cs:
<code>Copypublic MainWindow() { InitializeComponent(); ChangeToken.OnChange(()
=> App.MyConfigration.GetReloadToken(),()
=> { MessageBox.Show("文件發生變更了"
); }); } /<code>
效果如下:
六.強類型綁定配置#
首先我們創建一個類用於綁定配置,代碼如下:
<code>Copypublic
class
MyHumanConfig
{public
string
Name {get
;set
; }public
Body Body {get
;set
; }public
string
Sex {get
;set
; }public
int
Age {get
;set
; }public
bool
IsStudent {get
;set
; } }public
class
Body
{public
int
Height {get
;set
; }public
int
Weight {get
;set
; } } /<code>
在Mainwindow.cs新增以下代碼:
<code>Copy
private
void
Button_Click
(object
sender, RoutedEventArgs e) { LoadEnv(); LoadJson(); LoadXML(); LoadIni(); LoadBind(); }private
void
LoadBind
() {var
bindString =string
.Empty; MyHumanConfig config =new
MyHumanConfig(); App.MyConfigration.GetSection("Human"
).Bind(config);foreach
(var
configPropertyin
config.GetType().GetProperties()) {if
(configProperty.PropertyType==typeof
(Body)) {var
body = configProperty.GetValue(config)as
Body;foreach
(var
bodyPropertyin
body.GetType().GetProperties()) { bindString +=$"
{bodyProperty.Name}
:{bodyProperty.GetValue(body)}
\n"; } }else
{ bindString +=$"
{configProperty.Name}
:{configProperty.GetValue(config)}
\n"; } }this
.textbox_bind.Text = bindString; } /<code>
效果如下:
關鍵字: textbox item MyConfigration