您好,登錄后才能下訂單哦!
ASP.NET Core中修改配置文件后自動加載新配置的案例分析?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!
前言
在 ASP.NET Core 默認的應用程序模板中, 配置文件的處理如下面的代碼所示:
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 兩個配置文件都是可選的, 并且支持當文件被修改時能夠重新加載。
可以在 ASP.NET Core 應用中利用這個特性, 實現修改配置文件之后, 不需要重啟應用, 自動加載修改過的配置文件, 從而減少系統停機的時間。 實現的步驟如下:
使用配置 API 進行注入
假設要在程序中注入這樣一個配置類型:
public class WeatherOption { public string City { get; set; } public int RefreshInterval { get; set; } }
在 appsettings.json 中添加的配置如下:
{ "weather": { "city": "GuangZhou", "refreshInterval": 120 } }
在 Startup.cs 的 ConfigureServices 方法中使用配置 API 進行注入, 代碼如下:
public void ConfigureServices(IServiceCollection services) { services.Configure<WeatherOption>(Configuration.GetSection("weather")); services.AddControllers(); }
這個步驟很關鍵, 通過這個配置 API 可以把注入內容和配置所在的節點關聯起來。 如果有興趣了解底層實現的話, 可以繼續查看這個 OptionsConfigurationServiceCollectionExtensions.cs 。
通過這種方式注冊的內容, 都是支持當配置文件被修改時, 自動重新加載的。
在控制器 (Controller) 中加載修改過后的配置
控制器 (Controller) 在 ASP.NET Core 應用的依賴注入容器中注冊的生命周期是 Scoped , 即每次請求都會創建新的控制器實例。 這樣只需要在控制器的構造函數中注入 IOptionsSnapshot<TOption> 參數即可, 代碼如下:
[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; } }
當然, 如果不希望在控制器中使用這個 IOptionsSnapshot 接口類型(會帶來一些對現有代碼重構和修改, 還是有一定的風險的), 可以在 ConfigureServices 中添加對 WeatherOption 的注入, 代碼如下:
public void ConfigureServices(IServiceCollection services) { services.Configure<WeatherOption>(Configuration.GetSection("weather")); // 添加對 WeatherOption 的注入, 生命周期為 Scoped , 這樣每次請求都可以獲取新的配置值。 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; } }
這樣控制器就無需修改任何代碼即可加載修改過后的新配置。
在中間件 (Middleware) 中加載修改過后的配置
中間件 (Middleware) 在 ASP.NET Core 應用的依賴注入容器中注冊的生命周期是 Singleton , 即單例的, 只有在當應用啟動時, 根據中間件創建處理連時創建一次全局實例, 所以只能通過注入 IOptionsMonitor<T> 來監聽配置文件的修改情況, 示例代碼如下:
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)); } }
當然, 在中間件的 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)); }
但是這么做的話, 似乎就偏離了依賴注入的原則了, 因此不推薦這種做法。
感謝各位的閱讀!看完上述內容,你們對ASP.NET Core中修改配置文件后自動加載新配置的案例分析大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。