Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core ConfigureAppConfiguration adding additional sources overriding environment specific settings

When using the IConfigurationBuilder in a .NET Core 2.1 application with a Generic Host I configure 4 sources; but after the scope of ConfigureAppConfiguration there are 6 sources.

At some point 2 additional source I have already loaded are added a second time in an order that is causing appsettings.Environment.json values to be hidden. I have also tried removing the hostsettings.json configuration and verified that is not affecting this. This is for an Azure Webjob using WebjobsSDK 3.0 and .Net Core 2.1

    var builder = new HostBuilder()
        .ConfigureHostConfiguration(configurationBuilder =>
        {
             //This is to do some basic host configuration and should only add 2 sources
         configurationBuilder.SetBasePath(Directory.GetCurrentDirectory());
                configurationBuilder.AddJsonFile("hostsettings.json", optional: true);
                configurationBuilder.AddEnvironmentVariables(prefix: "APPSETTING_ASPNETCORE_");
            })
            .ConfigureAppConfiguration((hostContext, configurationBuilder) =>
            {
                //at this point there are 0 sources in the sources
                IHostingEnvironment env = hostContext.HostingEnvironment;
                configurationBuilder.SetBasePath(Directory.GetCurrentDirectory());
                configurationBuilder.AddJsonFile("appSettings.json", optional: false, reloadOnChange: true)
                    .AddJsonFile($"appSettings.{env.EnvironmentName}.json", optional: true,
                        reloadOnChange: true);
                configurationBuilder.AddEnvironmentVariables(prefix: "APPSETTING_ASPNETCORE_");
               //at this point there are 4 sources
            })
            .ConfigureServices((hostContext, servicesCollection) =>
            {
                //now there are 6, 2 additional source that are duplicates
                servicesCollection.Configure<IConfiguration>(hostContext.Configuration);

})

I expect a configuration provider with only the 4 sources, including the ChainedConfigSource, I have setup to be included. But 2 additional sources are added which are duplicates of the appsettings.json and the environment variables which I declared before loading the environment specific appsettings.environment.json.

Now when injected the into a class the appsettings.json settings were added last are returned over a appsettings.environment.json

like image 487
Ryan Holsman Avatar asked Dec 20 '18 16:12

Ryan Holsman


People also ask

How do you inject IConfiguration in NET Core 6?

You could add the IConfiguration instance to the service collection as a singleton object in ConfigureServices : public void ConfigureServices(IServiceCollection service) { services. AddSingleton<IConfiguration>(Configuration); //... }

What does webhost CreateDefaultBuilder () do?

CreateDefaultBuilder()Initializes a new instance of the WebHostBuilder class with pre-configured defaults.


2 Answers

But 2 additional sources are added which are duplicates of the appsettings.json and the environment variables

I had a similar issue with an Azure WebJob using the HostBuilder, and noticed that these 2 source were appended to the end of the list of config sources. This had undesirable results: development settings from appsettings.json overwrote the production settings fromappsettings.Production.json.

These additional sources appear to be added here by by ConfigureWebJobs.

The fix was to re-order the HostBuilder call chain so that the call to ConfigureWebJobs comes before the call to ConfigureAppConfiguration. These extra two sources are still present, but since they are now at the start of the list of configuration sources, and not at the end, they have no undesirable effects.

like image 130
Anthony Avatar answered Sep 18 '22 21:09

Anthony


Reading the source code for the Hostbuilder.cs class you will see that the Configuration added in the AddHostingConfiguration gets added to the ApplicationConfiguration.

Let me show you, you can find the source at https://github.com/aspnet/AspNetCore/blob/1c3fa82908fe2cb773626b6613843213286a482b/src/Microsoft.Extensions.Hosting/HostBuilder.cs

The build call will first create the HostingConfiguration, then the AppConfiguration.

Here's the code that builds the HostingConfiguration

    private void BuildHostConfiguration()
    {
        var configBuilder = new ConfigurationBuilder();
        foreach (var buildAction in _configureHostConfigActions)
        {
            buildAction(configBuilder);
        }
        _hostConfiguration = configBuilder.Build();
     }

Now in the BuildAppConfiguration you will see that the HostingConfiguration gets added ontop of the AppConfiguration

    private void BuildAppConfiguration()
    {
        var configBuilder = new ConfigurationBuilder();
        //Here _hostConfiguration gets added ontop
        configBuilder.AddConfiguration(_hostConfiguration);
        foreach (var buildAction in _configureAppConfigActions)
        {
            buildAction(_hostBuilderContext, configBuilder);
        }
        _appConfiguration = configBuilder.Build();
        _hostBuilderContext.Configuration = _appConfiguration;
    }

Now the Build functions are private and there is no way to reset/clear sources from the builder.

If you dont want to implement your own version of the HostBuilder I'd suggest not seperating the Host settings from your Appsettings

like image 37
Patrik Nyman Avatar answered Sep 19 '22 21:09

Patrik Nyman