static void

ASP.Net Core Configuration Settings

Web.config no longer exists, so connection strings and other settings must be stored in other files- json or xml or environmental variables.

ConfigurationBuilder

In a web application, it is done as part of Host.CreateDefaultBuilder(args), or, in .net 6, WebApplication.CreateBuilder(args)

The default order is (later ones override earlier ones):

You can customise it in the Program.cs (net 1-5 code). NB CreateDefaultBuilder in core 3.1 (and WebApplication in net 6) automatically reads all the sources in order- there is no need to specify them manually unless you're doing something special.

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureHostConfiguration(builder =>
        {
            //intended to set environment (DEV, PROD)
            //optional, but if used, call this BEFORE ConfigureAppConfiguration
            builder.AddEnvironmentVariables(); //if you've set DOTNET_ENVIRONMENT= "Production"
        })
        .ConfigureAppConfiguration((contextbuilder) =>
        {
            //optional, these are done automatically if you don't specify this...
            builder.Sources.Clear(); //clear the default ones from CreateDefaultBuilder
            builder.SetBasePath(Environment.CurrentDirectory);
            builder.AddJsonFile("appsettings.json"optionaltruereloadOnChangetrue);
            builder.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json"optionaltruereloadOnChangetrue);
            builder.AddEnvironmentVariables();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

In .net 6 there is a ConfigurationManager class, which looks similar, but adds the sources when you do builder.Add() ... builder.Build() is a no-op. This helps avoid scenarios when some config is needed for another (eg config in database).

Manual ConfigurationBuilder

In .net 6 consoles, there's no equivalent to WebApplication.CreateBuilder and we're stuck with the old Host.CreateDefaultBuilder(args). For consoles, it imposes an AddHostedService() using a type of IHostedService, which you have to implement. It's usually overkill, but you can get standard configuration out of it (and services too if required).

Most minimal: Install Microsoft.Extensions.Configuration.Json and Microsoft.Extensions.Configuration.Binder

var config = new ConfigurationBuilder()
   .AddJsonFile("appsettings.json")
   .Build();

var settings = config.GetRequiredSection("Settings").Get<Settings>();

Hacky, but gets appsettings.[env].json just like asp, and you could build and get the services.

IConfiguration configuration = null;
string environmentName = null;
var builder= Host.CreateDefaultBuilder(args)
    .ConfigureServices((contextservices) =>
    {
        configuration = context.Configuration;
        environmentName= context.HostingEnvironment.EnvironmentName;
        services.AddTransient<IMyService, MyService>();
    })
    .Build();

var settings = configuration.GetRequiredSection("Settings").Get<Settings>();

var myService = builder.Services.GetService<IMyService>();

var runner = new Runner(environmentName, settings, myService);
runner.Run();

Using config settings

ConfigurationBuilder creates an IConfiguration object, a bag containing all your settings. The standard dependency injection will plug it into your constructors (including Startup.cs)

private readonly IConfiguration _configuration;
public RecordController(IConfiguration configuration)
{
    _configuration = configuration;
}

You can access the values (including connection strings) as follows:

//connection strings - "ConnectionStrings": {"DB": "Data Source=..."}
var connectionString = _configuration.GetConnectionString("DB");
//get values (with a default)
var myValue = _configuration.GetValue<string>("myValue""myDefault");
//get sections with binding
var config = new ApiConfig();
_configuration.GetSection("ApiConfig").Bind(config);
//easier get sections
var config2 = _configuration.Get<ApiConfig>();

IOptions

You don't want to load the entire configuration into every class that just requires specific keys. The Options pattern breaks the config into small sections, with a simple poco class. This is registered with the DI (as services.Configure).

public void ConfigureServices(IServiceCollection services)
{
    //load the configuration into a poco
    services.Configure<MySettings>(Configuration.GetSection("a:b"));
}

The dependency injection can then load an IOptions<MySettings> into anything (IOptions is in Microsoft.Extensions.OptionsModel).

public void Service(IOptions<MySettings> settings)
{
    var mysettings = settings.Value;
    //do something with it
}