asp.net core重新載入應用配置 Intro 我把配置放在了資料庫或者是Redis里,配置需要修改的時候我要直接修改資料庫,然後調用一個介面去重新載入應用配置,於是就嘗試寫一個運行時重新載入配置的介面。 Configuration 重新載入實現 重新載入配置的介面其實很簡單,經過看 的源碼可 ...
asp.net core重新載入應用配置
Intro
我把配置放在了資料庫或者是Redis里,配置需要修改的時候我要直接修改資料庫,然後調用一個介面去重新載入應用配置,於是就嘗試寫一個運行時重新載入配置的介面。
Configuration 重新載入實現
重新載入配置的介面其實很簡單,經過看 Configuration
的源碼可以知道,如果想要重新載入應用配置,需要一個 IConfigurationRoot
對象,而 IConfigurationRoot
其實可以直接拿註入服務中的 IConfiguration
對象,服務中的 IConfiguration
對象也是實現了 IConfigurationRoot
介面的實例。後面我們一起看源碼就更清晰了。
來看實現重新載入配置的代碼
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
namespace TestWebApplication.Controllers
{
[Route("api/[controller]")]
public class ConfigurationsController : Controller
{
private readonly IConfigurationRoot _configuration;
public ConfigurationsController(IConfiguration configuration)
{
_configuration = configuration as IConfigurationRoot;
}
[HttpGet]
public IActionResult Get()
{
return Ok(new
{
RootUser = _configuration.GetAppSetting("RootUser") // 這裡 GetAppSetting 是一個自定義擴展方法,獲取AppSettings 節點下的配置信息
});
}
[HttpPut]
public IActionResult Put()
{
_configuration.Reload();
return Ok();
}
}
}
是不是很簡單,下麵我們來嘗試一下,你可以參考這個示例項目
因為預設的項目配置會監聽 appsettings.json 文件是否修改,如果已修改就會重新reload,這裡我新加一個文件,這裡設置 reloadOnChange
為 false
,示例代碼如下:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(configBuilder =>
{
configBuilder.AddJsonFile("abc.json", optional: true, reloadOnChange: false);
})
.UseStartup<Startup>();
abc.json 的文件內容如下:
{
"AppSettings": {
"TestNumber": 12,
"RootUser": "WeihanLi"
}
}
dotnet run
啟動網站,然後在瀏覽器中訪問 http://localhost:5000/api/configurations
然後我們修改 abc.json 文件
{
"AppSettings": {
"TestNumber": 12,
"RootUser": "WeihanLi 123"
}
}
修改保存之後刷新剛纔的頁面,可以看到還是剛纔的內容,證明並沒有重新載入配置,接下來嘗試我們的重新載入配置方法
使用 postman 或 fiddler 或其他你喜歡的工具發一個 PUT 請求到 http://localhost:5000/api/configurations
,這裡我使用 postman 調用 PUT 介面重新載入配置
返回 200 即介面調用成功,重新刷新剛纔的頁面就可以看到頁面上的數據已經發生變化,這也就證明瞭我們重新載入配置的介面生效了。
源碼解析
來看 ConfigurationBuilder
在 Build 的時候做了什麼,ConfigurationBuilder
源碼
可以看到這裡最後返回的是一個 IConfigurationRoot
對象,再來看 IConfigurationRoot
源碼
可以看到 IConfigurationRoot
定義了一個 Reload
的方法,這個方法會從下麵的 Providers
中重新載入配置,看到這裡我們就知道可以通過 IConfiguration
的 Reload
方法來重新載入應用程式的配置了,然後我們來看 WebHost.CreateDefaultBuilder(args).Build()
做了什麼
https://github.com/aspnet/AspNetCore/blob/master/src/DefaultBuilder/src/WebHost.cs#L149
這裡我們可以看到為什麼 appsettings.json 文件會自動 reload 配置,可以看到最後返回了一個 WebHostBuilder
對象
看 Asp.Net core WebHostBuilder
對象的 Build
方法 https://github.com/aspnet/AspNetCore/blob/master/src/Hosting/Hosting/src/WebHostBuilder.cs#L135
在 BuildCommonServices
可以看到這樣一段代碼 https://github.com/aspnet/AspNetCore/blob/master/src/Hosting/Hosting/src/WebHostBuilder.cs#L277
上面我們已經知道 ConfigurationBuilder
Build 之後返回的是一個 IConfigurationRoot
對象,而這裡註入是一個 IConfiguration
對象(IConfigurationRoot
實現 IConfiguration
介面),所以我們就可以從依賴註入中獲取 IConfiguration
對象直接當作 IConfigurationRoot
來使用,這也就是為什麼我們會直接獲取一個 IConfiguration
對象直接 as IConfigurationRoot
Memo
到此就暫時結束了,希望你能有所收穫~