一、設定組態檔即時生效
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 有三種方式
1. IOptions<T> //站台啟動後,取得的值永遠不變
2. IOptionsMonitor<T> //站台啟動後,如果組態檔有變化會發佈事件 (載入設定時,reloadOnChange:true 必須為 true)
3. 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();
}
}