web-dev-qa-db-ja.com

IOptionsMonitorとIOptionsSnapshotの違い

この回答 によると、IOptionsMonitorはDIコンテナーにsingletonとして登録され、変更を検出することができます。 OnChangeイベントサブスクリプション。 CurrentValueプロパティがあります。

一方、IOptionsSnapshotscopedとして登録され、各リクエストの最後のオプションを読み取ることで変更検出機能も備えていますが、 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を使用する理由/時期

私はそれをまっすぐに得たとは思わない、これらの依存性注入に関するいくつかの非常に重要な側面を見逃しているに違いない。

12
natenho

コメントには、Tsengを要約/繰り返すためのかなり良い回答がすでにあります。

IOptionsSnapshotは、スコープまたは一時的なオブジェクトに注入するのに最適です。そのオブジェクトの存続期間と一致し、新しいオブジェクトを取得すると新しい値が入ります。

ただし、シングルトンでリロードするオプションが必要な場合は、シングルトンが変更されないため、IOptionsMonitorを使用する必要があります。そのようなサービスの良い例は、Asp.net Coreで長時間実行されるバックグラウンドサービスのIHostedServiceから継承されたサービスです。

2
Paul Miller