在 Singleton 服务中使用 IOptionsMonitor 在运行时从 appsettings 重新加载值

Use IOptionsMonitor in Singleton service to reload values from appsettings on runtime

我目前正在开发 ASP.NET Core 2.2/.NET Framework 4.7.2 应用程序(我必须在我的 .NET Framework 4.7 中安装 .NET Core 2.2 作为框架.2 应用)。我需要在单例服务中从我的 appsettings.json 文件中检索值(这些值可以通过手动更改 appsettings.json 文件在 runtime 上更改)。这很好用。然而,想要的 reloadOnChange 不起作用。

当我在运行时更改 appsettings.json 文件中的值然后触发对我的服务逻辑的新请求时,未检索到新值。我已经尝试将我的单例服务注入作用域,不幸的是徒劳无功 - 结果相同,没有更新配置。

我真的不知道为什么 appsettings.json 的更新值在运行时从未出现在我的服务 class 中。

我的 CreateWebHostBuilder 方法如下所示:

public IWebHostBuilder CreateWebHostBuilder()
{
    var config = new ConfigurationBuilder()
       .SetBasePath(Directory.GetCurrentDirectory())
       .AddJsonFile(configFilePath, optional: false, reloadOnChange: true)
       .Build();

       return WebHost.CreateDefaultBuilder()
            .UseStartup<Startup>()
            .UseConfiguration(config);
 }

我的 Startup class 看起来像这样:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public static IConfiguration Configuration { get; private set; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<AppSettings>(Configuration);

        services.AddSingleton<IFruitService, FruitService>();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    { }
}

我的 FruitService 看起来像这样:

public class FruitService : IFruitService
{
    private readonly IOptionsSnapshot<AppSettings> appSettings;

    public PomService(IOptionsSnapshot<AppSettings> appSettings)
    {
        this.appSettings = appSettings;

    }

    public async Task<FruitMix> StartFruitMix(List<Fruit> fruits)
    {
        // here I would need the changed values from the appsettings.json,
        // but always the same, no change in any request...
        var a = appSettings.Value.Test;
        var b = appSettings.Value;
        var c = appSettings.Get("");

    }
}

我的AppSettingsclass很简单:

public class AppSettings
{
    public string Test { get; set; }
}

我的 appsettings.json 看起来像这样:

{
  "test": "1234" // during runtime when I manually change 1234 to sadf or 567 nothing happens in my service class on a new request (nor in singleton neither in scoped mode... I cannot retrieve the new value in my service class.)
}

你知道如何在 FruitService class 中检索更改的值吗?

非常感谢

选项,即使启用了重新加载,在请求的生命周期内也不会改变。然而,听起来你实际上已经提出了新的要求,但发现选项仍然没有改变。

我个人还没有遇到需要专门使用 IOptionsMonitor<TOptions> 的场景。但是,我知道它在内部使用缓存并且具有手动使所述缓存中的选项无效的能力。它可能实际上不会在更改时自动重新加载 - 不确定。

无论如何,更典型的做法是使用 IOptionsSnapshot<TOptions>。这仅用于根据请求重新加载选项,因此它似乎可以满足您的需求。 IOptionsMonitor<TOptions> 的唯一好处似乎是它能够实际监视更改并通知回调。再说一遍,我还没有充分利用它来判断你是否只是做错了什么,但我认为你 实际上 无论如何都不需要这个。