Search code examples
c#asp.netjsonconfigurationconfiguration-files

ASP.NET 5: How to reload strongly typed configuration on change


I have been able to set up strongly typed configuration in ASP.NET 5, and it works perfectly. I have also set the configuration to reload automatically when the .json configuration files are changed. But this only seems to work if I use the untyped configuration. The strongly typed configuration class still retains the old values when the .json files are changed.

I'm setting up configuration like this:

public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
    // Setup configuration sources
    var builder = new ConfigurationBuilder()
        .AddJsonFile("config.json")
        .AddJsonFile($"config.{env.EnvironmentName}.json");
    Configuration = builder.Build()
        .ReloadOnChanged("config.json")
        .ReloadOnChanged($"config.{env.EnvironmentName}.json");
    /* ... (unrelated stuff edited away) ... */
}

And binding it like this:

public void ConfigureServices(IServiceCollection services)
{
    /* ... (unrelated stuff edited away) ... */
    services.AddOptions();
    services.AddInstance(Configuration);
    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
    services.Configure<DbSettings>(Configuration.GetSection("DbSettings"));
    /* ... (unrelated stuff edited away) ... */
}

(The configuration files looks like this:)

{
    "AppSettings": {
        "This": "that",
        "Foo": "bar"
        /* etc... */
    },
    "DbSettings": {
        /* (db settings here) */
    }
}

(And I correspondingly have a C# class like this:)

public class AppSettings
{
    public string This { get; set; }
    public string Foo { get; set; }
    /* etc... */
}

When I acquire the IOptions<AppSettings> via dependency injection, it doesn't change when I change the config.json and config.Dev.json files. I have to restart the entire web app to make the config class update. But if I instead use the untyped IConfiguration instance, it automatically changes when I change the json files.

So the question is: How to make the strongly typed configuration change when I change the .json file, without having to restart the webapp?


Solution

  • It's been a while since ASP.NET 5, but currently the docs are clear - with the IOptions<T> the changes are not read. IOptionsSnapshot or IOptionsMonitor offer that feature.

    https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-8.0#the-options-pattern

    The changes are also read when Bind is used, or the Get<T> method, but not just calling the GetSection