上一篇 ASP.NET Core - 選項系統之選項設定 中提到 IOptions
public class OptionController : ControllerBase
{
private readonly BlogOptions _blogOptions;
public OptionController(IOptions<BlogOptions> options)
{
// 通過 IOptions<TOptions> 介面的 Value 屬性讀取選項類
// 選項類始終是程式啟動時載入的值,不會改變
_blogOptions = options.Value;
}
}
public class OptionController : ControllerBase
{
private readonly BlogOptions _blogOptions;
public OptionController(IOptionsSnapshot<BlogOptions> optionsSnapshot)
{
// IOptionsSnapshot<TOptions> 可以通過 Value 屬性讀取預設的命名的選項類, Options 物件範例建立時讀取的設定快照
_blogOptions = optionsSnapshot.Value;
// 也可以通過 Get 方法獲取某一個命名選項,沒有指定命名時,預設命名為 string.Empty
//_blogOptions = optionsSnapshot.Get(string.Empty);
}
}
public class OptionController : ControllerBase
{
private readonly BlogOptions _blogOptions;
public OptionController(IOptionsMonitor<BlogOptions> optionsMonitor)
{
// IOptionsMonitor<TOptions> 介面沒有 Value 屬性,通過 CurrentValue 獲取選項類物件,
// 每次呼叫 CurrentValue都會實時讀取設定源,始終是最新設定的值
_blogOptions = optionsMonitor.CurrentValue;
// 該介面也支援通過 Get 方法獲取命名選項
_blogOptions = optionsMonitor.Get(string.Empty);
// 可以通過 OnChange 註冊事件,當設定被載入時會觸發事件
optionsMonitor.OnChange(OnOptionsChange);
}
[HttpGet]
public Task<BlogOptions> Get()
{
return Task.FromResult(_blogOptions);
}
private void OnOptionsChange(BlogOptions options)
{
Console.WriteLine(JsonSerializer.Serialize(options));
}
}
啟動應用,呼叫一次 Get 介面,在 Api 控制器建構函式中註冊了設定載入觸發事件,之後修改 appsettings.json 組態檔中選項類對於的設定節點內容,可以看到事件觸發,控制檯中輸出了改變之後的選項類內容。
三個介面解析的選項類的差別,可以通過以下測試清楚得看出:
組態檔中初始選項節點如下:
"Blog": {
"Title": "ASP.NET Core Options11",
"Content": "This is a blog about Options System in ASP.NET Core Framework.",
"CreateTime": "2022-12-06"
}
這裡為了方便看出 Scoped 生命週期 IOptionSnapeshoot
public class OptionController : ControllerBase
{
private readonly IOptions<BlogOptions> _blogOptions;
private readonly IOptionsSnapshot<BlogOptions> _blogSnapshotOptions;
private readonly IOptionsMonitor<BlogOptions> _blogMonitorOptions;
public OptionController(
IOptions<BlogOptions> options,
IOptionsSnapshot<BlogOptions> optionsSnapshot,
IOptionsMonitor<BlogOptions> optionsMonitor
)
{
// 注意這裡不能再把選項類物件先讀取出來,否則選項類物件也不會再改變了
_blogOptions = options;
_blogSnapshotOptions = optionsSnapshot;
_blogMonitorOptions = optionsMonitor;
}
[HttpGet]
public Task Get()
{
Console.WriteLine("第一次讀取設定:");
Console.WriteLine("IOptions<TOptions>:" + JsonSerializer.Serialize(_blogOptions.Value));
Console.WriteLine("IOptionsSnapshot<TOptions>:" + JsonSerializer.Serialize(_blogSnapshotOptions.Value));
Console.WriteLine("IOptionsMonitor<TOptions>:" + JsonSerializer.Serialize(_blogMonitorOptions.CurrentValue));
Console.WriteLine("請修改組態檔!");
Console.ReadKey();
Console.WriteLine("第二次讀取設定:");
Console.WriteLine("IOptions<TOptions>:" + JsonSerializer.Serialize(_blogOptions.Value));
Console.WriteLine("IOptionsSnapshot<TOptions>:" + JsonSerializer.Serialize(_blogSnapshotOptions.Value));
Console.WriteLine("IOptionsMonitor<TOptions>:" + JsonSerializer.Serialize(_blogMonitorOptions.CurrentValue));
return Task.CompletedTask;
}
}
之後啟動應用呼叫 Get 介面,並在過程中將組態檔內容修改為以下:
"Blog": {
"Title": "ASP.NET Core Options222",
"Content": "This is a blog about Options System in ASP.NET Core Framework.",
"CreateTime": "2022-12-06"
}
可以看到控制檯的輸出中,第二次讀取設定的時候,IOptionsMonitor
之後不要關閉應用,再調一次 Get 介面,並在過程中再次修改設定如下:
"Blog": {
"Title": "ASP.NET Core Options333",
"Content": "This is a blog about Options System in ASP.NET Core Framework.",
"CreateTime": "2022-12-06"
}
這一次的 Get 請求的輸出結果如下:
可以看到 IOptionsMonitor
參考文章:
ASP.NET Core 中的選項模式 | Microsoft Learn
選項模式 - .NET | Microsoft Learn
面向 .NET 庫建立者的選項模式指南 - .NET | Microsoft Learn
理解ASP.NET Core - 選項(Options)
ASP.NET Core 系列:
目錄:ASP.NET Core 系列總結
上一篇:ASP.NET Core - 選項系統之選項設定