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)加載修改過的配置文件, 從而減少系統(tǒng)停機(jī)的時(shí)間。 實(shí)現(xiàn)的步驟如下:
使用配置 API 進(jìn)行注入
假設(shè)要在程序中注入這樣一個(gè)配置類型:
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)鍵, 通過這個(gè)配置 API 可以把注入內(nèi)容和配置所在的節(jié)點(diǎn)關(guān)聯(lián)起來(lái)。 如果有興趣了解底層實(shí)現(xiàn)的話, 可以繼續(xù)查看這個(gè) OptionsConfigurationServiceCollectionExtensions.cs 。
通過這種方式注冊(cè)的內(nèi)容, 都是支持當(dāng)配置文件被修改時(shí), 自動(dòng)重新加載的。
在控制器 (Controller) 中加載修改過后的配置
控制器 (Controller) 在 ASP.NET Core 應(yīng)用的依賴注入容器中注冊(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 接口類型(會(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> 類型了, 最終控制器的代碼如下:
[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ú)需修改任何代碼即可加載修改過后的新配置。
在中間件 (Middleware) 中加載修改過后的配置
中間件 (Middleware) 在 ASP.NET Core 應(yīng)用的依賴注入容器中注冊(cè)的生命周期是 Singleton , 即單例的, 只有在當(dāng)應(yīng)用啟動(dòng)時(shí), 根據(jù)中間件創(chuàng)建處理連時(shí)創(chuàng)建一次全局實(shí)例, 所以只能通過注入 IOptionsMonitor<T> 來(lái)監(jiān)聽配置文件的修改情況, 示例代碼如下:
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)); }
但是這么做的話, 似乎就偏離了依賴注入的原則了, 因此不推薦這種做法。
總結(jié)
到此這篇關(guān)于ASP.NET Core中修改配置文件后自動(dòng)加載新配置的文章就介紹到這了,更多相關(guān)ASP.NET Core自動(dòng)加載新配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Visual Studio 2017開發(fā)環(huán)境的安裝圖文教程
Visual Studio 2017是微軟于2017年3月8日正式推出的新版本,是迄今為止 最具生產(chǎn)力 的 Visual Studio 版本。這篇文章主要介紹了Visual Studio 2017開發(fā)環(huán)境的安裝,需要的朋友可以參考下2017-11-11告別ADO.NET實(shí)現(xiàn)應(yīng)用系統(tǒng)無(wú)縫切換的煩惱(總結(jié)篇)
說(shuō)起ADO.NET,就扯上了數(shù)據(jù)庫(kù)訪問類庫(kù)了,現(xiàn)在的每個(gè)項(xiàng)目的數(shù)據(jù)庫(kù)訪問類應(yīng)該說(shuō)都很強(qiáng)的了,經(jīng)常就聽到說(shuō)我的我們的數(shù)據(jù)庫(kù)訪問類怎么怎么強(qiáng)大而且支持多數(shù)據(jù)庫(kù),現(xiàn)在的大家做的項(xiàng)目里用的數(shù)據(jù)庫(kù)訪問類庫(kù)我想也都是支持多數(shù)據(jù)庫(kù)吧,支持到什么程度我就不知道了2009-11-11asp.net 退出登陸(解決退出后點(diǎn)擊瀏覽器后退問題仍然可回到頁(yè)面問題)
退出登陸是再常見不過的了,先清除Session,再轉(zhuǎn)到登陸頁(yè)面2009-04-04MVC使用Spring.Net應(yīng)用IOC(依賴倒置)學(xué)習(xí)筆記3
這篇文章主要為大家詳細(xì)介紹了MVC使用Spring.Net應(yīng)用IOC(依賴倒置),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Path類與Directory類與File類對(duì)路徑/目錄/文件的操作實(shí)例
本文將詳細(xì)介紹下:Path對(duì)路徑字符串進(jìn)行操作/Directory和DirectoryInfo 對(duì)目錄進(jìn)行操作/File和FileInfo對(duì)文件進(jìn)行操作,感興趣的你可不要錯(cuò)過了哈2013-02-02獲取創(chuàng)建Membership的數(shù)據(jù)庫(kù)創(chuàng)建腳本
membership的數(shù)據(jù)庫(kù)可以通過aspnet_regsql.exe來(lái)配置生成,但是里面的東西,不一定都是我需要的,有時(shí)我也想自定義一些東西。2010-02-02在asp.net中使用加密數(shù)據(jù)庫(kù)聯(lián)接字符串保證數(shù)據(jù)安全
加密web.config可以有效保證數(shù)據(jù)庫(kù)用戶和密碼安全,下面是示例代碼,大家可以看看2014-09-09