Passaggio all'ora solare 25 ottobre 2020 03:0002:00 sposta indietro l'orologio di 1 ora (si dorme 1 ora in più)
In una console application .NET Core 3.1 è possibile leggere i valori contenuti nel file di configurazione appsettings.json con il codice seguente.

Saranno necessari i seguenti pacchetti Nuget:
dotnet add package Microsoft.Extensions.Hosting
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.FileExtensions
dotnet add package Microsoft.Extensions.Configuration.Json
dotnet add package Microsoft.Extensions.Configuration.Binder 
dotnet add package Newtonsoft.Json
Nel file di configurazione appsettings.json, andrà aggiunta una sezione, ad esempio di nome AppSettings e un'altra di nome ConnectionStrings, ad esempio:
{
    ...
    "ConnectionStrings": {
        "Main": "Server=.\\sqlexpress;Database=MioDB;Integrated Security=True;"
    },
    "AppSettings": {
        "TenantID": "a32e5240-7d2a-469d-9542-6232b132bda9",
        "ClientID": "44252521-12e4-47e3-b7fa-1d1e837d634b",
        "ClientSecret": "fi3J87._tf9x21x~da_Z.eGaaJ1sI61tj5"
    },
    ...
}
che verrà poi automaticamente mappato su una classe AppSettings a cui vanno aggiunte le stesse proprietà presenti nel file di configurazione:
[JsonObject("AppSettings")]
using Newtonsoft.Json;

public class AppSettings
{
	public string TenantID { get; set; }

	public string ClientID { get; set; }

	public string ClientSecret { get; set; }
}
Poi va creato l'host ( in Program.cs) per configurare la dipendency injection e il file di configurazione:
private static IHost GetHost()
{
	var hostBuilder = new HostBuilder()
		.ConfigureServices((hostContext, services) =>
		{
			// specifico qual'è il file con la configurazione
			IConfigurationRoot configuration = new ConfigurationBuilder()
				.SetBasePath(System.IO.Directory.GetCurrentDirectory())
				.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
				.Build();

			// aggiungo le varie dependency tra cui la configurazione
			services.AddSingleton<IConfiguration>(configuration);

			// e la mia classe di esempio
			services.AddTransient<SgartTestAppSettings>();
		}).UseConsoleLifetime();

	return hostBuilder.Build();
}
Servirà anche una classe di esempio dove userò i valori letti dal file di configurazione:
public class SgartTestAppSettings
{
	private readonly IConfiguration cfg;
	private readonly AppSettings settings;

	// il parametro cfg verrà valorizzato tramite la dependency injection
	public SgartTestAppSettings(IConfiguration cfg)
	{
		this.cfg = cfg;

		// leggo la sezione AppSettings e la mappo sulla classe corrispondente
		this.settings = cfg.GetSection("AppSettings").Get<AppSettings>();
	}

	public async Task Run()
	{
		// stampo i valori letti dal file di configurazione nella sezione AppSettings
		Console.WriteLine($"TenantID: {settings.TenantID}");

		// stampo i valori letti dal file di configurazione nella sezione ConnectionString
		Console.WriteLine($"Connection string 'Main': {cfg.GetConnectionString("Main")}");
	}
}
infine eseguo lo startup nel file Program.cs
class Program
{
    static void Main(string[] args)
    {
        try
        {
            // istanzio l'host
            var host = GetHost();

            using (var serviceScope = host.Services.CreateScope())
            {
                var services = serviceScope.ServiceProvider;

                // creo la app
                var runner = services.GetRequiredService<SgartTestAppSettings>();
                runner.Run().Wait();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            throw ex;
        }
    }
}


Nell'esempio precedente il mapping è stato fatto nel costruttore della classe SgartTestAppSettings tramite l'istruzione this.settings = cfg.GetSection("AppSettings").Get<AppSettings>();.
Esiste anche un alternativa che consiste nel configurare la classe AppSettings come dependency injection:
private static IHost GetHost()
{
	var hostBuilder = new HostBuilder()
		.ConfigureServices((hostContext, services) =>
		{
			// specifico qual'è il file con la configurazione
			IConfigurationRoot configuration = new ConfigurationBuilder()
				.SetBasePath(System.IO.Directory.GetCurrentDirectory())
				.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
				.Build();

			// aggiungo le varie dependency tra cui la configurazione
			services.AddSingleton<IConfiguration>(configuration);

			// configuro il mapping su AppSettings come dependency injection
			services.AddSingleton<AppSettings>(configuration.GetSection("AppSettings").Get<AppSettings>());

			// e la mia classe di esempio
			services.AddTransient<SgartTestAppSettings>();
		}).UseConsoleLifetime();

	return hostBuilder.Build();
}
a questo punto si può modificare il costruttore della classe SgartTestAppSettings per includere anche AppSettings:
public class SgartTestAppSettings
{
    private readonly IConfiguration cfg;
    private readonly AppSettings settings;

    // gestisco anche il parametro settings tramite la dependency injection 
    public SgartTestAppSettings(IConfiguration cfg, AppSettings settings)
    {
        this.cfg = cfg;
        // salvo la classe settings
        this.settings = settings;
    }

    public async Task Run()
    {
        Console.WriteLine($"TenantID: {settings.TenantID}");

        // la connection string continuo a leggerla tramite cfg
        Console.WriteLine($"Connection string 'Main': {cfg.GetConnectionString("Main")}");
    }
}