根据这个答案 https://stackoverflow.com/a/46570073/1987788, IOptionsMonitor
在 DI 容器中注册为单例并且能够通过以下方式检测变化OnChange
事件订阅。它有一个CurrentValue
财产。
另一方面,IOptionsSnapshot
注册为scoped并且还具有通过读取每个请求的最后选项来进行更改检测的功能,但它不具备OnChange
事件。它有一个Value
财产。
例如,使用两者注入视图可以给我们带来完全相同的行为:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Options;
using UsingOptionsSample.Models;
using UsingOptionsSample.Services;
namespace UsingOptionsSample.Pages
{
public class MyOptions
{
public MyOptions()
{
// Set default value.
Option1 = "value1_from_ctor";
}
public string Option1 { get; set; }
public int Option2 { get; set; } = 5;
}
public class OptionsTestModel : PageModel
{
private readonly MyOptions _snapshotOptions;
private readonly MyOptions _monitorOptions;
public OptionsTestModel(
IOptionsMonitor<MyOptions> monitorOptionsAcessor,
IOptionsSnapshot<MyOptions> snapshotOptionsAccessor)
{
_snapshotOptions = snapshotOptionsAccessor.Value;
_monitorOptions = monitorOptionsAcessor.CurrentValue;
}
public string SnapshotOptions { get; private set; }
public string MonitorOptions { get; private set; }
public void OnGetAsync()
{
//Snapshot options
var snapshotOption1 = _snapshotOptions.Option1;
var snapshotOption2 = _snapshotOptions.Option2;
SnapshotOptions =
$"snapshot option1 = {snapshotOption1}, " +
$"snapshot option2 = {snapshotOption2}";
//Monitor options
var monitorOption1 = _monitorOptions.Option1;
var monitorOption2 = _monitorOptions.Option2;
MonitorOptions =
$"monitor option1 = {monitorOption1}, " +
$"monitor option2 = {monitorOption2}";
}
}
}
那么,如果这两个接口/实现看起来像相同的东西,只是具有不同的生命周期,那么它们有什么意义呢?代码是基于此样本 https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/configuration/options/sample,令人惊讶的是,其中不包括IOptionsMonitor
使用示例。
如果两者都返回选项的“当前值”,为什么一个具有“Value”属性而另一个具有“CurrentValue”?
为什么/什么时候应该使用IOptionsSnapshot
代替IOptionsMonitor
?
我认为我没有弄清楚,我一定错过了有关这些和依赖项注入的一些非常重要的方面。