26

In two projects (a .NET Core Web API and a .NET Core WindowsService) I am using appsettings.json for the configuration.

 var configuration = new ConfigurationBuilder()
           .SetBasePath(System.IO.Directory.GetCurrentDirectory())
           .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
           .AddEnvironmentVariables()
           .Build();

In both I have the reloadOnChange set to true and using it as injected IOptions via dependency injection. Within the web api into the controller classes and within the service into the classes that use the settings.

Unfortunatly I experience that the values do not change when the appsettings.json changes.

On the web api I created a controller to just return a string value from the config and this stays the same as on startup.

So my questions:

  1. Anyone knows if that should work out of the box (at least in the web api)?
  2. Anything I have to do that it works?
monty
  • 7,888
  • 16
  • 63
  • 100
  • How are you registering your options? Do you use `services.Configure(Confiugration.GetSection(...))`? or do you use `.Bind()`? – Tseng Apr 11 '17 at 08:54
  • In both cases services.Configure(Confiugration.GetSection(.‌​..)) – monty Apr 11 '17 at 08:57
  • 1
    Normally it works via change tokens whcih are registered when you call the above overload (https://github.com/aspnet/Options/blob/rel/1.1.0/src/Microsoft.Extensions.Options.ConfigurationExtensions/OptionsConfigurationServiceCollectionExtensions.cs#L35-L36) and https://github.com/aspnet/Options/blob/rel/1.1.0/src/Microsoft.Extensions.Options.ConfigurationExtensions/ConfigureFromConfigurationOptions.cs triggers a rebind when the token is fired – Tseng Apr 11 '17 at 09:08
  • @Tseng could you please describe it in more detail? – Lukas Hieronimus Adler Jan 12 '18 at 12:06
  • 1
    @LukasHieronimusAdler you just use AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) with reloadOnChange true. if you use IOptionsSnapshot in the constructor where the depenendies are injected instead of IOptions you will always get the updated snapshot injected. The trick still is to track know when your instances are created. Some services are registered as singletons therefor the options get only injected once and do not receive updated versions of the settings (since no more injection is done). e.g. on DBContext connection strings.... – monty Jan 18 '18 at 06:48
  • @monty Thanks for your help but i don't get it. I have the IOptionsSnapshot in Controllers which is working great. But now i also would likte to use IOptionsSnapshot in my normal classes. In this case, i can not access it, becouse if i would like to create a object (in the constructor i added IOptionsSnapshot like in the controller classes) it's needed to pass a object from the type IOptionsSnapshot to it. But i have no idea where i can get it from – Lukas Hieronimus Adler Jan 19 '18 at 13:32
  • 2
    @LukasHieronimusAdler you can "query" your IOptionsSnapshot like any other service from the ServiceProvider in Microsoft.Extensions.DependencyInjection, e.g. like YourCustomOptionsClass options = ServiceProvider.GetService>().Value; Everytime you query the options it will be the newest version. If you query Options instead of IOptionsSnapshot it would not get updated. (As far as I know so far). – monty Jan 22 '18 at 09:29
  • @monty how can i access the ServiceProvider Class? Its not allowed to create an object of ServiceProvider... Thanks for your unbelievable good help :) – Lukas Hieronimus Adler Jan 22 '18 at 10:27
  • @LukasHieronimusAdler well, that depends on which project type you are developing. Do you implement a web api or ASP Net Core MVC web project or some other type? – monty Jan 22 '18 at 12:47
  • @monty i develop in asp net core mvc – Lukas Hieronimus Adler Jan 22 '18 at 12:48
  • @LukasHieronimusAdler In the constructor off a controller you could define IServiceProvider serviceProvider and it will be injected. From there on you could pass the reference to your class and so on and on... Please also mind that I haven't tested the reloadOnChange feature successfully for my scenario so far. I just try to help you out with what I know so far. – monty Jan 22 '18 at 13:41

1 Answers1

11

Assuming you are using .net-core 1.1 (because reloadOnChange is only supported in ASP.NET Core 1.1 and higher) it's actually IOptionsSnapshot you want (cf. Configuration in ASP.NET Core - IOptionsSnapshot) rather than just IOptions.

Boggin
  • 3,251
  • 3
  • 33
  • 48
  • haven't got it working so far but I will keep trying – monty Apr 14 '17 at 12:48
  • 2
    This worked for me! I am injecting `IOptions` via constructor. Changing it to `IOptionsSnapshot` makes it update on file change without having to restart the app. – Doctor Blue Feb 27 '18 at 13:46
  • Can you please provide an example of how to use IOptionsSnapshot and do I need to create a wrapper for my settings file? – Fandango68 Aug 26 '22 at 04:57