ASP.NET Core中修改配置文件后自動(dòng)加載新配置的方法詳解
前言
在 ASP.NET Core 默認(rèn)的應(yīng)用程序模板中, 配置文件的處理如下面的代碼所示:
config.AddJsonFile(
path: "appsettings.json",
optional: true,
reloadOnChange: true
);
config.AddJsonFile(
path: $"appsettings.{env.EnvironmentName}.json",
optional: true,
reloadOnChange: true
);
appsettings.json 和 appsettings.{env.EnvironmentName}.json 兩個(gè)配置文件都是可選的, 并且支持當(dāng)文件被修改時(shí)能夠重新加載。
可以在 ASP.NET Core 應(yīng)用中利用這個(gè)特性, 實(shí)現(xiàn)修改配置文件之后, 不需要重啟應(yīng)用, 自動(dòng)加載修改過(guò)的配置文件, 從而減少系統(tǒng)停機(jī)的時(shí)間。 實(shí)現(xiàn)的步驟如下:
使用配置 API 進(jìn)行注入
假設(shè)要在程序中注入這樣一個(gè)配置類(lèi)型:
public class WeatherOption {
public string City { get; set; }
public int RefreshInterval { get; set; }
}
在 appsettings.json 中添加的配置如下:
{
"weather": {
"city": "GuangZhou",
"refreshInterval": 120
}
}
在 Startup.cs 的 ConfigureServices 方法中使用配置 API 進(jìn)行注入, 代碼如下:
public void ConfigureServices(IServiceCollection services) {
services.Configure<WeatherOption>(Configuration.GetSection("weather"));
services.AddControllers();
}
這個(gè)步驟很關(guān)鍵, 通過(guò)這個(gè)配置 API 可以把注入內(nèi)容和配置所在的節(jié)點(diǎn)關(guān)聯(lián)起來(lái)。 如果有興趣了解底層實(shí)現(xiàn)的話(huà), 可以繼續(xù)查看這個(gè) OptionsConfigurationServiceCollectionExtensions.cs 。
通過(guò)這種方式注冊(cè)的內(nèi)容, 都是支持當(dāng)配置文件被修改時(shí), 自動(dòng)重新加載的。
在控制器 (Controller) 中加載修改過(guò)后的配置
控制器 (Controller) 在 ASP.NET Core 應(yīng)用的依賴(lài)注入容器中注冊(cè)的生命周期是 Scoped , 即每次請(qǐng)求都會(huì)創(chuàng)建新的控制器實(shí)例。 這樣只需要在控制器的構(gòu)造函數(shù)中注入 IOptionsSnapshot<TOption> 參數(shù)即可, 代碼如下:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase {
private WeatherOption option;
public WeatherForecastController(
IOptionsSnapshot<WeatherOption> options
) {
this.option = options.Value;
}
// GET /weatherforcase/options
[HttpGet("options")]
public ActionResult<WeatherOption> GetOption() {
return options;
}
}
當(dāng)然, 如果不希望在控制器中使用這個(gè) IOptionsSnapshot 接口類(lèi)型(會(huì)帶來(lái)一些對(duì)現(xiàn)有代碼重構(gòu)和修改, 還是有一定的風(fēng)險(xiǎn)的), 可以在 ConfigureServices 中添加對(duì) WeatherOption 的注入, 代碼如下:
public void ConfigureServices(IServiceCollection services) {
services.Configure<WeatherOption>(Configuration.GetSection("weather"));
// 添加對(duì) WeatherOption 的注入, 生命周期為 Scoped , 這樣每次請(qǐng)求都可以獲取新的配置值。
services.AddScoped(serviceProvider => {
var snapshot = serviceProvider.GetService<IOptionsSnapshot<WeatherOption>>();
return snapshot.Value;
});
services.AddControllers();
}
這樣在控制器中就不需要注入 IOptionsSnapshot<T> 類(lèi)型了, 最終控制器的代碼如下:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase {
private WeatherOption option;
public WeatherForecastController(
WeatherOption option
) {
this.option = option;
}
// GET /weatherforcase/options
[HttpGet("options")]
public ActionResult<WeatherOption> GetOption() {
return options;
}
}
這樣控制器就無(wú)需修改任何代碼即可加載修改過(guò)后的新配置。
在中間件 (Middleware) 中加載修改過(guò)后的配置
中間件 (Middleware) 在 ASP.NET Core 應(yīng)用的依賴(lài)注入容器中注冊(cè)的生命周期是 Singleton , 即單例的, 只有在當(dāng)應(yīng)用啟動(dòng)時(shí), 根據(jù)中間件創(chuàng)建處理連時(shí)創(chuàng)建一次全局實(shí)例, 所以只能通過(guò)注入 IOptionsMonitor<T> 來(lái)監(jiān)聽(tīng)配置文件的修改情況, 示例代碼如下:
public class TestMiddleware {
private RequestDelegate next;
private WeatherOption option;
public TestMiddleware(
RequestDelegate next,
IOptionsMonitor<WeatherOption> monitor
) {
this.next = next;
option = monitor.CurrentValue;
// moni config change
monitor.OnChange(newValue => {
option = newValue;
});
}
public async Task Invoke(HttpContext context) {
await context.Response.WriteAsync(JsonSerializer.Serialize(option));
}
}
當(dāng)然, 在中間件的 Task Invoke(HttpContext context) 方法中, 直接獲取 IOptionsSnapshot<T> 也是可以的, 代碼如下:
public async Task Invoke(HttpContext context) {
var snapshot = context.RequestServices.GetService<IOptionsSnapshot<WeatherOption>>();
await context.Response.WriteAsync(JsonSerializer.Serialize(snapshot.Value));
}
但是這么做的話(huà), 似乎就偏離了依賴(lài)注入的原則了, 因此不推薦這種做法。
總結(jié)
到此這篇關(guān)于ASP.NET Core中修改配置文件后自動(dòng)加載新配置的文章就介紹到這了,更多相關(guān)ASP.NET Core自動(dòng)加載新配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET?MVC擴(kuò)展帶驗(yàn)證的單選按鈕
這篇文章實(shí)現(xiàn)了ASP.NET?MVC擴(kuò)展帶驗(yàn)證的單選按鈕功能,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09
asp.net下實(shí)現(xiàn)URL重寫(xiě)技術(shù)的代碼
asp.net下實(shí)現(xiàn)URL重寫(xiě)技術(shù)的代碼...2007-10-10
.net調(diào)用存儲(chǔ)過(guò)程詳細(xì)介紹
本文的數(shù)據(jù)庫(kù)用的是sql server自帶數(shù)據(jù)Northwind2013-04-04
.NET Core API CORS的實(shí)現(xiàn)
這篇文章主要介紹了.NET Core API CORS的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
一個(gè)ASP.NET中使用的MessageBox類(lèi)
一個(gè)ASP.NET中使用的MessageBox類(lèi)...2006-09-09
.NET中實(shí)現(xiàn)對(duì)象數(shù)據(jù)映射示例詳解
這篇文章主要為大家介紹了.NET中實(shí)現(xiàn)對(duì)象數(shù)據(jù)映射示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10

