.NET Core,.NET5預設配置都是隻載入一次,修改配置時都需要重啟才能生效,如何能修改即時生效呢,下面來演示一遍。
一、設定配置檔案實時生效
1.1配置
在Program.cs的CreateHostBuilder()處增加載入配置檔案的時候,reloadOnChange:true。
這樣配置檔案修改的時候,程式就會監聽到檔案發生變化,自動重新載入了。
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
1.2驗證
appsettings.json檔案內容如下
{ "TestSetting": "123", "AppOptions": { "UserName": "zhangsan" } }
程式碼:
public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private readonly IConfiguration _configuration; public HomeController(ILogger<HomeController> logger, IConfiguration configuration) { _logger = logger; _configuration = configuration; } public IActionResult Index() { string Name = _configuration["TestSetting"]; string Name2 = _configuration["AppOptions:UserName"]; ViewBag.Name = Name; ViewBag.Name2 = Name2; return View(); } }
介面顯示:
把配置檔案修改為:
{ "TestSetting": "abc", "AppOptions": { "UserName": "zhangsan123" } }
重新整理頁面,已經發生變化:
1.3 IOptions方式實時生效
新建AppOptions.cs類
/// <summary> /// 配置檔案 /// </summary> public class AppOptions { public string UserName { get; set; } }
在Startup.cs處把配置加到Options
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.Configure<AppOptions>(Configuration.GetSection("AppOptions")); }
使用:
public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private readonly IConfiguration _configuration; private IOptionsMonitor<AppOptions> _options; public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IOptionsMonitor<AppOptions> appOptions) { _logger = logger; _configuration = configuration; _options = appOptions; } public IActionResult Index() { string Name = _configuration["TestSetting"]; string Name2 = _options.CurrentValue.UserName; ViewBag.Name = Name; ViewBag.Name2 = Name2; return View(); } }
IOptions有三種方式
//IOptions<T> //站點啟動後,獲取到的值永遠不變 //IOptionsMonitor<T> //站點啟動後,如果配置檔案有變化會發布事件 (載入配置時,reloadOnChange:true 必須為true) //IOptionsSnapshot<T> //站點啟動後,每次獲取到的值都是配置檔案裡的最新值 (載入配置時,reloadOnChange:true 必須為true)
注意:
IOptionsMonitor<T> 和 IOptionsSnapshot<T> 的最大區別是前者可以被其他的Singleton Services使用而後者不可以, 因為前者被註冊為Singleton 而後者是被註冊為Scoped,也就是說檔案被修改了前者會立即Reload,而後者是在每個請求才被Reload。
例:
public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private UserService _userService; public HomeController(ILogger<HomeController> logger, UserService userService) { _userService = userService; } public IActionResult Index() { string Name2 = _userService.GetName(); ViewBag.Name2 = Name2; return View(); } }
public class UserService { private IOptionsMonitor<AppOptions> _options; public UserService(IOptionsMonitor<AppOptions> appOptions) { _options = appOptions; } public string GetName() { var Name = _options.CurrentValue.UserName; return Name; } }
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.Configure<AppOptions>(Configuration.GetSection("AppOptions")); services.AddSingleton<UserService>(); }
上面的UserService是單例注入的,通過IOptionsMonitor<T>的方式是可以實現配置實時重新整理的,而IOptionsSnapshot<T>啟動就會報錯。
1.4多個配置檔案載入實時生效
增加多一個db配置檔案
修改Program.cs處CreateHostBuilder(),也是載入時加上reloadOnChange:true 就可以了。
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); config.AddJsonFile("Configs/dbsetting.json", optional: true, reloadOnChange: true); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
使用也是一樣的:
public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private readonly IConfiguration _configuration; private AppOptions _options; public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IOptionsMonitor<AppOptions> appOptions) { _logger = logger; _configuration = configuration; _options = appOptions.CurrentValue; } public IActionResult Index() { string Name = _configuration["TestSetting"]; string Name2 = _configuration["db:connection1"]; ViewBag.Name = Name; ViewBag.Name2 = Name2; return View(); } }