この回答 によると、IOptionsMonitor
はDIコンテナーにsingletonとして登録され、変更を検出することができます。 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}";
}
}
}
それで、これらの2つのインターフェース/実装が同じものに見え、寿命が異なるだけである場合、それは何のポイントですか?コードは このサンプルに基づく であり、意外にもIOptionsMonitor
の使用サンプルは含まれていません。
両方がオプションの「現在の値」を取得する場合、一方に「Value」プロパティがあり、他方に「CurrentValue」があるのはなぜですか?
IOptionsSnapshot
の代わりにIOptionsMonitor
を使用する理由/時期
私はそれをまっすぐに得たとは思わない、これらの依存性注入に関するいくつかの非常に重要な側面を見逃しているに違いない。
コメントには、Tsengを要約/繰り返すためのかなり良い回答がすでにあります。
IOptionsSnapshotは、スコープまたは一時的なオブジェクトに注入するのに最適です。そのオブジェクトの存続期間と一致し、新しいオブジェクトを取得すると新しい値が入ります。
ただし、シングルトンでリロードするオプションが必要な場合は、シングルトンが変更されないため、IOptionsMonitorを使用する必要があります。そのようなサービスの良い例は、Asp.net Coreで長時間実行されるバックグラウンドサービスのIHostedService
から継承されたサービスです。