为什么 IOptionsMonitor<T>.OnChange 没有被调用?

Dov*_*Dov 6 c# dependency-injection .net-core .net-core-3.1

我想让我的 .Net Core 3.1 应用程序在磁盘上的文件更改时自动重新加载其配置,但我无法使其与选项模式一起使用。我运行我的应用程序,保存对配置文件的更改,但它从未被调用。为什么 IOptionsMonitor 实例不调用 OnChange 处理程序?我缺少什么?

Program.cs IHostBuilder 创建

Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration(config => configuration = config.Build())
    .ConfigureServices((hostContext, services) => {
        var separateConfig = new ConfigurationBuilder()
            .AddJsonFile("SeparateConfig.json", optional: false, reloadOnChange: true)
            .Build();

        services
            .AddSingleton<MyMainService>()
            .Configure<MySeparateConfig>(c => separateConfig.Bind(c));
    })
Run Code Online (Sandbox Code Playgroud)

使用 MySeparateConfig 的服务

public class MyMainService
{
    public MyMainService(IOptionsMonitor<MySeparateConfig> config)
    {
        if (config is null) throw new ArgumentNullException(nameof(config));

        ConfigChangeHandle = config.OnChange(UpdateConfiguration);
        
        // Perform initial configuration using config.CurrentValue here
    }

    private IDisposable ConfigChangeHandle { get; set; }
    
    private void UpdateConfiguration(MySeparateConfig config)
    {
        // Never called
    }
}
Run Code Online (Sandbox Code Playgroud)

Dov*_*Dov 12

正如@Nkosi 在评论中指出的那样,这一行就是问题所在:

    // Wrong
    .Configure<MySeparateConfig>(c => separateConfig.Bind(c));
Run Code Online (Sandbox Code Playgroud)

当我用下面的行替换它时,一切都开始正常工作:

    // Right
    .Configure<MySeparateConfig>(separateConfig);
Run Code Online (Sandbox Code Playgroud)


0xc*_*ced 6

为了使重新加载机制能够使用IOptionsMonitor<TOptions>IOptionsChangeTokenSource<TOptions>需要在服务中注册。

\n

例如,如果您需要OptionsBuilder<TOptions>添加验证,则可以使用AddOptions+来实现BindConfiguration(如果您在 ASP.NET Core 中没有依赖项,则可以从Microsoft.Extensions.Options.ConfigurationExtensions NuGet 包中获得)

\n
services.AddOptions<MyConfig>().BindConfiguration("").Validate(\xe2\x80\xa6)\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,BindConfiguration扩展方法会自动注册,这IOptionsChangeTokenSource<TOptions>是重新加载机制工作所需的魔力。

\n