asp.net-core - IOptionsMonitor 与 IOptionsSnapshot 之间的区别
问题描述
根据这个答案,IOptionsMonitor
在 DI 容器中注册为单例,并且能够通过OnChange
事件订阅检测更改。它有一个CurrentValue
属性。
另一方面,IOptionsSnapshot
注册为范围,并且还具有通过读取每个请求的最后一个选项来检测更改的能力,但它没有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}";
}
}
}
那么,如果这两个接口/实现看起来一样,只是生命周期不同,那么拥有这两个接口/实现有什么意义呢?该代码基于此示例,令人惊讶的是它不包含IOptionsMonitor
使用示例。
如果两者都返回选项的“当前值”,为什么一个具有“值”属性而另一个具有“当前值”?
为什么/何时应该使用IOptionsSnapshot
而不是IOptionsMonitor
?
我不认为我说得通,我一定遗漏了一些关于这些和依赖注入的非常重要的方面。
解决方案
IOptionsMonitor
是一个随时检索当前选项值的单例服务,这在单例依赖项中特别有用。
IOptionsSnapshot
是一个范围服务,并在构造对象时提供选项的快照。IOptionsSnapshot<T>
选项快照设计用于瞬态和范围依赖项。
IOptions<T>
当您不希望配置值更改时使用。IOptionsSnaphot<T>
当您期望您的值发生变化但希望它在整个请求中保持一致时使用。IOptionsMonitor<T>
当您需要实时值时使用 。
推荐阅读
- java - “显示注释...”快捷方式在 Eclipse 2020-12 (4.18.0) 中不再有效
- python - 位置参数遵循 Django ORM 查询中的关键字参数问题
- twig - Twig:用包含替换字符串中的占位符
- javascript - 不变违规:组件`article`的视图配置getter回调必须是一个函数(收到`undefined`)
- swift - Firestore 中的 updateData() 函数存在问题
- java - 如何将模拟注入需要构造函数参数的 bean
- cypress - 如何使用 cypress-repeat 仅重新运行失败的场景?
- javascript - 角度点击事件更新变量但不是javascript onclick方法
- sql - 在databricks SQL中的字段中输出分号分隔的值
- python - 拟合自定义 Scipy 分布