Lymn
Lymn

Reputation: 75

ConfigurationBuilder with strongly typed configuration

How do you create a ConfigurationBuilder that searches for an environment variable and then, if it did not find any, uses the appSetting parameter instead?

My code currently:

public void ConfigureServices(IServiceCollection services)
{
    // Get configuration
    var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
    var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddEnvironmentVariables()
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
        .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: false)
        .Build();
    var settings = new AppSettings();
    configuration.GetSection("App").Bind(settings);

    // ...

    services.AddSingleton<ILogger, LogConsole>()
        .AddSingleton<IDatabaseManager, PostgresDatabaseManager>()
        .AddSingleton<IDbConnectionFactory, PostgreDbConnectionFactory>()
        .Configure<AppSettings>(configuration.GetSection("App"))
        .AddOptions()
        .BuildServiceProvider();
}

Problem is that the line ".Configure<AppSettings>(configuration.GetSection("App"))" only keeps what is in AppSettings, but as seen here:

img

configuration has all my environment variables (Count = 89) and the AppSettings variables.

I tried following things found here:
https://www.jerriepelser.com/blog/aspnet-core-no-more-worries-about-checking-in-secrets/

But I'm under the impression that this type of configuration does not match well with strongly typed configuration.

Upvotes: 0

Views: 737

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239380

That's how things work by default. The order you define configuration providers matters. ASP.NET Core will use them in that same order. Basically, all it does is collect values from each source and puts them in a dictionary. As each further source is utilized, it either adds additional key-value pairs to the dictionary or overwrites existing key-value pairs, just as dictionaries always do. This creates a simplistic but effective override ability, as the last config source you add will always have the last say on a particular key's value.

For example, in your situation here. Environment variables are loaded in first. Then, your JSON files will be parsed and any values there will be added. Therefore, if you did not define a particular environment variable, the value for it will by default come from the JSON file(s).

If you want things the opposite way around, where if an environment variable is set, that value and not the one defined in your JSON files is the one that should be used, simply change the order of your providers:

.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
.AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: false)
.AddEnvironmentVariables()

Upvotes: 1

Related Questions