在Singleton服务中使用IOptionsMonitor在运行时从应用程序设置中重新加载值

时间:2019-02-07 16:11:37

标签: c# .net configuration asp.net-core-2.2

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

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

我真的不知道为什么appsettings.json中的更新值永远不会在运行时出现在我的服务类中。

我的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类看起来像这样:

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("");

    }
}

我的AppSettings类非常简单:

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类中检索更改的值吗?

非常感谢您

1 个答案:

答案 0 :(得分:1)

即使启用了重新加载,选项在请求期间也不会更改。但是,听起来您实际上已经发出了一个新请求,但发现这些选项仍未更改。

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

无论如何,更典型的是使用IOptionsSnapshot<TOptions>。仅存在此问题是为了按请求重新加载选项,因此似乎可以满足您的需求。 IOptionsMonitor<TOptions>的唯一好处似乎在于它实际上可以监视更改并通知回调的能力。再说一次,我还没有用到足够的信息来告诉您您是否只是在做错什么,但我认为您实际上仍然需要这样做。