IOptionsMonitor与IOptionsSnapshot之间的区别

时间:2018-06-10 23:44:07

标签: asp.net-core dependency-injection interface options object-lifetime

根据this answerIOptionsMonitor在DI容器中注册为 singleton ,并且能够通过OnChange事件订阅检测更改。它有CurrentValue属性。

另一方面,IOptionsSnapshot注册为范围,并且通过阅读每个请求的最后选项也具有更改检测功能,但它没有{ {1}}事件。它有OnChange属性。

例如,将两个注入到视图中都会给我们提供完全相同的行为:

Value

那么,如果这两个接口/实现看起来像是同一个东西,只有不同的生命周期,那么它是什么意思呢?代码为based on this sample,但不包含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}"; } } } 使用样本。

为什么一个人拥有&#34;价值&#34;财产和其他有&#34; CurrentValue&#34;如果两者都获得&#34;当前值&#34;期权?

为什么/何时应该使用IOptionsMonitor代替IOptionsSnapshot

我不认为我做到了直接,我必须忽略一些关于这些依赖注入的非常重要的方面。

2 个答案:

答案 0 :(得分:5)

IOptionsMonitor是一种单例服务,可随时检索当前选项值,这在单例依赖项中特别有用。

IOptionsSnapshot作用域服务,并在构造IOptionsSnapshot<T>对象时提供选项的快照。选项快照被设计为与 transient scoped 依赖项一起使用。

当您不希望配置值达到以下要求时,请使用IOptions<T> 更改。当您期望自己的价值观达到目标时,请使用IOptionsSnaphot<T> 更改,但希望在整个请求中保持一致。采用 IOptionsMonitor<T>,当您需要实时值时。

答案 1 :(得分:1)

这些评论已经有一些不错的答案,可以尝试总结/重复Tseng。

IOptionsSnapshot非常适合注入到作用域或瞬态对象中。这将与该对象的生命周期保持一致,并且在获取新对象时会引入新的值。

但是,如果您需要在单例中重新加载的选项,则应该使用IOptionsMonitor,因为单例永远不会改变。此类服务的一个很好的例子是从IHostedService继承的服务,用于Asp.net Core中长期运行的后台服务。