创建一个类型为IOptionsMonitor的实例或对象。尝试使用OptionsMonitor但出现构造函数参数错误。

3

我是C#和IOptionsMonitor概念的新手。

MyOptionsClass myOptionObject = new MyOptionClass ();
IOptions<MyOptionsClass> instaceOfIOptions =
    new OptionsWrapper<MyOptionsClass>(myOptionObject );

类似于它们用于获取“IOptions”的方法,我想要获取“IOptionsMonitor”的实例。我尝试了类似的方式,但它给我一个编译器错误。

IOptionsMonitor<CosmosDBOptions> instaceOfIOptionsMonitor =
    new OptionsMonitor<CosmosDBOptions>(myOptionObject);

但它要求传递3个参数(工厂、源和缓存),而不是myOptionObject

这里我需要传递什么参数呢?如何实现?


为什么?你实际上想要解决的问题是什么? - Jeremy Lakeman
IOptions通常与依赖注入一起使用,为什么你要直接构造一个OptionsMonitor呢?(https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) - Jeremy Lakeman
1个回答

0
在这种情况下,你需要实现 IOptionsMonitor<T>,例如:
private sealed class ValueBasedOptionsMonitor<TOptions> : IOptionsMonitor<TOptions>
    where TOptions : class
{
    private TOptions _value;

    public ValueBasedOptionsMonitor(TOptions value)
    {
        _value = value;
    }

    private event Action<TOptions, string>? OnChangeEvent;

    public TOptions CurrentValue
    {
        get => Get(string.Empty);
        set
        {
            if (_value == value)
            {
                return;
            }

            _value = value;
            OnChangeEvent?.Invoke(value, string.Empty);
        }
    }

    public TOptions Get(string name)
    {
        return _value;
    }

    public IDisposable OnChange(Action<TOptions, string> listener)
    {
        OnChangeEvent += listener;
        return Disposable.Create(() => OnChangeEvent -= listener);
    }
}

如果您不打算修改值,可以省略OnChangeEventCurrentValue的setter,并用虚拟实现替换OnChange
如果您需要根据配置部分创建IOptionsMonitor<T>实例(我需要),可以使用以下方法:
private sealed class SectionBasedOptionsMonitor<TOptions> : IOptionsMonitor<TOptions>, IDisposable
    where TOptions : class, new()
{
    private readonly IConfiguration _configuration;
    private readonly IDisposable _changeRegistration;

    private TOptions _options = new();

    public SectionBasedOptionsMonitor(IConfiguration configuration)
    {
        _configuration = configuration;
        _changeRegistration = ChangeToken.OnChange(configuration.GetReloadToken, HandleConfigurationChanged);

        UpdateOptions();
    }

    private event Action<TOptions, string>? OnChangeEvent;

    public TOptions CurrentValue => Get(string.Empty);

    public void Dispose()
    {
        _changeRegistration.Dispose();
    }

    public TOptions Get(string name)
    {
        // Don't support named options in this case.
        return _options;
    }

    public IDisposable OnChange(Action<TOptions, string> listener)
    {
        OnChangeEvent += listener;
        return Disposable.Create(() => OnChangeEvent -= listener);
    }

    private void UpdateOptions()
    {
        _options = new();
        _configuration.Bind(_options);
    }

    private void HandleConfigurationChanged()
    {
        UpdateOptions();
        OnChangeEvent?.Invoke(_options, string.Empty);
    }
}

但请记住,在这种情况下,实现是一次性的,所以您需要跟踪创建的实例并在某处处理它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接