Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm currently working on an ASP.NET Core 2.2/.NET Framework 4.7.2 application (I had to install .NET Core 2.2 as a Framework within my .NET Framework 4.7.2 application). I need to retrieve the values from my appsettings.json file (the values can change on runtime through manually changing the appsettings.json file) in a singleton service. This works fine. However, the desired reloadOnChange does not work.

When I change a value in my appsettings.json file on runtime and then trigger a new request to my service logic, the new values are not being retrieved. I already tried to inject my singleton service as scoped, unfortunately in vain - the same result, no updated configuration.

I really don't know why the updated values from appsettings.json never appear in my service class on runtime.

My CreateWebHostBuilder method looks like this:

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

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

My Startup class looks like this:

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)
    { }
}

My FruitService looks like this:

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

    }
}

My AppSettings class is very simple:

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

My appsettings.json looks like this:

{
  "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.)
}

Do you know how to retrieve the changed values in the FruitService class?

Thank you very much

like image 219
accordo777 Avatar asked Oct 25 '25 00:10

accordo777


1 Answers

Options, even with reload enabled, do not change during the life of a request. However, it sounds like you have in fact made a new request and found that the options have still not changed.

I personally haven't encountered a scenario where I've needed to use IOptionsMonitor<TOptions> specifically. However, I do know that it internally uses a cache and has a manual ability to invalidate options in said cache. It's possible that it does not in fact automatically reload on change - not sure about that.

Regardless, it's more typical to use IOptionsSnapshot<TOptions> instead. This exists solely to reload options per request, so it would seem to meet your needs here. The only benefit to IOptionsMonitor<TOptions> seems to be its ability to actually watch for changes and notify a callback. Again, I haven't used this enough to tell if you're simply doing something wrong, but I don't think you actually need this anyways.

like image 83
Chris Pratt Avatar answered Oct 26 '25 15:10

Chris Pratt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!