淺析.netcore中的Configuration具體使用
不管是.net還是.netcore項(xiàng)目,我們都少不了要讀取配置文件,在.net中項(xiàng)目,配置一般就存放在web.config中,但是在.netcore中我們新建的項(xiàng)目根本就看不到web.config,取而代之的是appsetting.json。
新建一個(gè)webapi項(xiàng)目,可以在startup中看到一個(gè)IConfiguration,通過(guò)框架自帶的IOC使用構(gòu)造函數(shù)進(jìn)行實(shí)例化,在IConfiguration中我們發(fā)現(xiàn)直接就可以讀取到appsetting.json中的配置項(xiàng)了,如果在控制器中需要讀取配置,也是直接通過(guò)構(gòu)造
函數(shù)就可以實(shí)例化IConfiguration對(duì)象進(jìn)行配置的讀取。下面我們?cè)囈幌逻\(yùn)行的效果,在appsetting.json添加一個(gè)配置項(xiàng),在action中可以進(jìn)行訪問(wèn)。

添加其他配置文件
那我們的配置項(xiàng)是不是只能寫在appsetting.json中呢?當(dāng)然不是,下面我們看看如何添加其他的文件到配置項(xiàng)中,根據(jù)官網(wǎng)教程,我們可以使用ConfigureAppConfiguration實(shí)現(xiàn)。
首先我們?cè)陧?xiàng)目的根目錄新建一個(gè)config.json,然后在其中隨意添加幾個(gè)配置,然后在program.cs中添加高亮顯示的部分,這樣很簡(jiǎn)單的就將我們新增的json文件中的配置加進(jìn)來(lái)了,然后在程序中就可以使用IConfiguration進(jìn)行訪問(wèn)config.json中的配置項(xiàng)了。
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(configure => {
configure.AddJsonFile("config.json"); //無(wú)法熱修改
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
但是這個(gè)無(wú)法在配置項(xiàng)修改后讀取到最新的數(shù)據(jù),我們可以調(diào)用重載方法configure.AddJsonFile("config.json",true,reloadOnChange:true)實(shí)現(xiàn)熱更新。
除了添加json文件外,我們還可以使用AddXmlFile添加xml文件,使用AddInMemoryCollection添加內(nèi)存配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context,configure) => {
Dictionary<string, string> memoryConfig = new Dictionary<string, string>();
memoryConfig.Add("memoryKey1", "m1");
memoryConfig.Add("memoryKey2", "m2");
configure.AddInMemoryCollection(memoryConfig);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
源碼解讀:
在自動(dòng)生成的項(xiàng)目中,我們沒(méi)有配置過(guò)如何獲取配置文件,那.netcore框架是怎么知道要appsetting.json配置文件的呢?我們通過(guò)查看源碼我們就可以明白其中的道理。
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
//CreateDefaultBuilder源碼
public static IHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new HostBuilder();
builder.UseContentRoot(Directory.GetCurrentDirectory());
builder.ConfigureHostConfiguration(config =>
{
config.AddEnvironmentVariables(prefix: "DOTNET_");
if (args != null)
{
config.AddCommandLine(args);
}
});
builder.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
});
....
return builder;
}
怎么樣?是不是很有意思,在源碼中我們看到在Program中構(gòu)建host的時(shí)候就會(huì)調(diào)用ConfigureAppConfiguration對(duì)應(yīng)用進(jìn)行配置,會(huì)讀取appsetting.json文件,并且會(huì)根據(jù)環(huán)境變量加載不同環(huán)境的appsetting,同時(shí)還可以看到應(yīng)用不僅添加了
appsetting的配置,而且添加了從環(huán)境變量、命令行傳入?yún)?shù)的支持,對(duì)于AddUserSecrets支持讀取用戶機(jī)密文件中的配置,這個(gè)在存儲(chǔ)用戶機(jī)密配置的時(shí)候會(huì)用到。
那為什么我們可以通過(guò)再次調(diào)用ConfigureAppConfiguration去追加配置信息,而不是覆蓋呢?我們同樣可以在源碼里面找到答案。
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
//以下為部分源碼
private List<Action<HostBuilderContext, IConfigurationBuilder>> _configureAppConfigActions = new List<Action<HostBuilderContext, IConfigurationBuilder>>();private IConfiguration _appConfiguration;
public IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate)
{
_configureAppConfigActions.Add(configureDelegate ?? throw new ArgumentNullException(nameof(configureDelegate)));
return this;
}
public IHost Build()
{
...
BuildAppConfiguration();
...
}
private void BuildAppConfiguration()
{
var configBuilder = new ConfigurationBuilder()
.SetBasePath(_hostingEnvironment.ContentRootPath)
.AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true);
foreach (var buildAction in _configureAppConfigActions)
{
buildAction(_hostBuilderContext, configBuilder);
}
_appConfiguration = configBuilder.Build();
_hostBuilderContext.Configuration = _appConfiguration;
}
框架聲明了一個(gè)List<Action<HostBuilderContext, IConfigurationBuilder>>,我們每次調(diào)用ConfigureAppConfiguration都是往這個(gè)集合中添加元素,等到Main函數(shù)調(diào)用Build的時(shí)候會(huì)觸發(fā)ConfigurationBuilder,將集合中的所有元素進(jìn)行循環(huán)追加
到ConfigurationBuilder,最后就形成了我們使用的IConfiguration,這樣一看對(duì)于.netcore中IConfiguration是怎么來(lái)的就很清楚了。
讀取層級(jí)配置項(xiàng)
如果需要讀取配置文件中某個(gè)層級(jí)的配置應(yīng)該怎么做呢?也很簡(jiǎn)單,使用IConfiguration["key:childKey..."]
比如有這樣一段配置:
"config_key2": {
"config_key2_1": "config_key2_1",
"config_key2_2": "config_key2_2"
}
可以使用IConfiguration["config_key2:config_key2_1"]來(lái)獲取到config_key2_1的配置項(xiàng),如果config_key2_1下還有子配置項(xiàng)childkey,依然可以繼續(xù)使用:childkey來(lái)獲取
選項(xiàng)模式獲取配置項(xiàng)
選項(xiàng)模式使用類來(lái)提供對(duì)相關(guān)配置節(jié)的強(qiáng)類型訪問(wèn),將配置文件中的配置項(xiàng)轉(zhuǎn)化為POCO模型,可為開(kāi)發(fā)人員編寫代碼提供更好的便利和易讀性
我們添加這樣一段配置:
"Student": {
"Sno": "SNO",
"Sname": "SNAME",
"Sage": 18,
"ID": "001"
}
接下來(lái)我們定義一個(gè)Student的Model類
public class Student
{
private string _id;
public const string Name = "Student";
private string ID { get; set; }
public string Sno { get; set; }
public string Sname { get; set; }
public int Sage { get; set; }
}
可以使用多種方式來(lái)進(jìn)行綁定:
1、使用Bind方式綁定
Student student = new Student(); _configuration.GetSection(Student.Name).Bind(student);
2、使用Get方式綁定
var student1 = _configuration.GetSection(Student.Name).Get<Student>(binderOptions=> {
binderOptions.BindNonPublicProperties = true;
});
Get方式和Bind方式都支持添加一個(gè)Action<BinderOptions>的重載,通過(guò)這個(gè)我們配置綁定時(shí)的一些配置,比如非公共屬性是否綁定(默認(rèn)是不綁定的),但是Get比BInd使用稍微方便一些,如果需要綁定集合也是一樣的道理,將Student
替換成List<Student>。
3、全局方式綁定
前兩種方式只能在局部生效,要想做一次配置綁定,任何地方都生效可用,我們可以使用全局綁定的方式,全局綁定在Startup.cs中定義
services.Configure<Student>(Configuration.GetSection(Student.Name));
此方式會(huì)使用選項(xiàng)模式進(jìn)行配置綁定,并且會(huì)注入到IOC中,在需要使用的地方可以在構(gòu)造函數(shù)中進(jìn)行實(shí)例化
private readonly ILogger<WeatherForecastController> _logger;
private readonly IConfiguration _configuration;
private readonly Student _student;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration, IOptions<Student> student)
{
_logger = logger;
_configuration = configuration;
_student = student.Value;
}
命名選項(xiàng)的使用
對(duì)于不同的配置節(jié),包含的配置項(xiàng)一樣時(shí),我們?cè)谑褂眠x項(xiàng)綁定的時(shí)候無(wú)需定義和注入兩個(gè)類,可以在綁定時(shí)指定名稱,比如下面的配置:
"Root": {
"child1": {
"child_1": "child1_1",
"child_2": "child1_2"
},
"child2": {
"child_1": "child2_1",
"child_2": "child2_2"
}
}public class Root{ public string child_1{get;set;} public string child_2{get;set;}}
services.Configure<Root>("Child1",Configuration.GetSection("Root:child1"));
services.Configure<Root>("Child2", Configuration.GetSection("Root:child2"));
private readonly ILogger<WeatherForecastController> _logger;
private readonly IConfiguration _configuration;
private readonly Student _student;
private readonly Root _child1;
private readonly Root _child2;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration, IOptions<Student> student,IOptionsSnapshot<Root> root)
{
_logger = logger;
_configuration = configuration;
_student = student.Value;
_child1 = root.Get("Child1");
_child2 = root.Get("Child2");
}
到此這篇關(guān)于淺析.netcore中的Configuration具體使用的文章就介紹到這了,更多相關(guān).net core Configuration內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決.net framework 4.0環(huán)境下遇到版本不同編譯不通過(guò)的方法詳解
本篇文章是對(duì).net framework 4.0環(huán)境下遇到版本不同編譯不通過(guò)的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
asp.net access web.config denied
如果出現(xiàn)這個(gè)問(wèn)題,最好首先檢查一下ASPNET的帳號(hào),是否有訪問(wèn)權(quán)限。2009-04-04
asp.net XMLHttpRequest實(shí)現(xiàn)用戶注冊(cè)前的驗(yàn)證
用戶注冊(cè)前的驗(yàn)證,提高用戶體驗(yàn)。2009-10-10
.NET6打包部署到Windows?Service的全過(guò)程
net用了這么久,雖然多數(shù)都是部署在centos系統(tǒng),但也有部署在windows上的情況,下面這篇文章主要給大家介紹了關(guān)于.NET6打包部署到Windows?Service的相關(guān)資料,需要的朋友可以參考下2022-10-10
asp.net繼承IHttpHandler接口實(shí)現(xiàn)給網(wǎng)站圖片添加水印功能實(shí)例
這篇文章主要介紹了asp.net繼承IHttpHandler接口實(shí)現(xiàn)給網(wǎng)站圖片添加水印功能,實(shí)例分析了asp.net基于IHttpHandler接口實(shí)現(xiàn)網(wǎng)站圖片水印功能的具體步驟與相關(guān)技巧,需要的朋友可以參考下2016-07-07

