根据this answer,IOptionsMonitor
以单例的形式注册在DI容器中,并且能够通过OnChange
事件订阅来检测更改。它具有CurrentValue
属性。
另一方面,IOptionsSnapshot
被注册为范围内的,并且通过读取每个请求的最后一个选项还具有更改检测功能,但是它没有OnChange
事件。它具有Value
属性。
例如,将两者都注入(inject)到 View 中将为我们提供完全相同的行为:
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}";
}
}
}
那么,如果这两个接口(interface)/实现看起来一样,只是寿命不同,那又有什么意义呢?该代码是based on this sample,但令人惊讶的是其中没有
IOptionsMonitor
用法示例。如果一个都拥有选项的“当前值”,为什么一个拥有“Value”属性而另一个拥有“CurrentValue”属性呢?
为什么/何时应该使用
IOptionsSnapshot
而不是IOptionsMonitor
?我认为我并没有直截了当,关于这些依赖项注入(inject),我一定缺少一些非常重要的方面。
最佳答案
这些评论已经有一些不错的答案,可以尝试总结/重复Tseng。
IOptionsSnapshot非常适合注入(inject)作用域或 transient 的对象。这将与该对象的生存期保持一致,并且在获取新对象时会引入新的值。
但是,如果您需要在单例中重新加载的选项,则应该使用IOptionsMonitor,因为单例永远不会改变。此类服务的一个很好的例子是从IHostedService
继承的服务,它们是Asp.net Core中长期运行的后台服务。
关于asp.net-core - IOptionsMonitor与IOptionsSnapshot之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50788988/