In questo articolo parliamo di Net Core c#, nello specifico come aggiungere e leggere dei parametri inseriti nel file “appsettings.json” all’interno di un progetto Console.
Normalmente un progetto Console, a differenza di progetti più indirizzati al Web come ad esempio API, non presenta di default il file di configurazione e le relative classi di memorizzazione.

Creare un nuovo Progetto

Quando viene realizzato un nuovo progetto Console in Net Core, oltre alle librerie di base verrà creato di default il file Program.cs con al suo interno un codice simile al seguente:

using System;

namespace TemplateConsoleProject
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("Hello World!");
		}
	}
}

Come si può notare, all’interno del file c’è una funzione sincrona di default denominata Main anche se per scelta personale (..e deformazione professionale..) tendo ad utilizzare sempre funzioni asincrone perché la maggior parte dei progetti opera su web e qualche chiamata resta sempre in attesa di risposta.
Per questo ora andremo ad aggiungere una funzione asincrona denominata MainAsync:

using System;
using System.Threading.Tasks;

namespace TemplateConsoleProject
{
	class Program
	{
		static void Main(string[] args)
		{
			MainAsync(args).Wait();
		}
		static async Task MainAsync(string[] args)
		{
			try
			{
				//future start await service
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}
	}
}

Creazione e modifica del file appsettings.json

Il prossimo passo sarà quello di creare il file appsettings.json nella Path principale del progetto.

Una volta creato il file, andremo a modificare il suo contenuto sostituendolo con quello descritto nel codice successivo:

{
    "ConnectionStrings": {
      "DefaultConnection": "Stringa_di_connessione_al_Database"
    },
    "User": {
      "UserName": "MioNome",
      "UserSurname": "MioCognome"
    }
}

Creazione del Model “Settings”

Il passaggio successivo sarà quello di creare il ModelSettings“. E’ buona norma pianificare una Path nel progetto che racchiuda tutti i Moldels. Creeremo la cartella Models e al suo interno andremo a realizzare il file Settings.cs come raffigurato nella seguente immagine:

All’interno del file Settings.cs inseriremo il seguente codice:

using System;
using System.Collections.Generic;
using System.Text;

using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace TemplateConsoleProject.Model
{
    public class Settings
    {
        [JsonProperty("ConnectionStrings")]
        public ConnectionStrings ConnectionStrings { get; set; }

        [JsonProperty("User")]
        public User User { get; set; }
    }

    public class ConnectionStrings
    {
        [JsonProperty("DefaultConnection")]
        public string DefaultConnection { get; set; }
    }

    public class User
    {
        [JsonProperty("UserName")]
        public string UserName { get; set; }

        [JsonProperty("UserSurname")]
        public string UserSurname { get; set; }
    }
}

Installazione Pacchetti

Il prossimo passaggio sarà quello di scaricare da Nuget i seguenti pacchetti:
– Newtonsoft.Json
– Microsoft.Extensions.DependencyInjection
– Microsoft.Extensions.Configuration
– Microsoft.Extensions.Configuration.FileExtensions
– Microsoft.Extensions.Configuration.Json

Una volta scaricate tutte le librerie andremo a modificare nuovamente il file Program.cs inserendo:
– I servizi (Singleton, Scoped e Transient)
– La lettura del file “appsettings.json”
– L’attribuzione dei valori letti dal file di configurazione al Model “Settings”
– L’attribuzione al Model Setting dei valori memorizzati nel servizio Singleton (servizio i cui valori vengono letti una sola volta senza variare l’allocazione di memoria).
Il codice che si otterrà sarà il seguente:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;
using TemplateConsoleProject.Model;

namespace TemplateConsoleProject
{
	class Program
	{
		static void Main(string[] args)
		{
			MainAsync(args).Wait();
		}
		static async Task MainAsync(string[] args)
		{
			// Istanziata la collezione di servizi 
			ServiceCollection serviceCollection = new ServiceCollection();
			ConfigureServices(serviceCollection);
			IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();

			try
			{
				//future start await service
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private static void ConfigureServices(IServiceCollection services)
		{
			// Lettura del file appsetings.json
			IConfigurationRoot conf = new ConfigurationBuilder()
				.SetBasePath(Environment.CurrentDirectory)
				.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
				.Build();

			// passaggio dei parametri al Model Settings
			var sets = new Settings();
			sets.User = new User();
			sets.ConnectionStrings = new ConnectionStrings();
			sets.User.UserName = conf.GetSection("User:UserName").Value;
			sets.User.UserSurname = conf.GetSection("User:UserSurname").Value;
			sets.ConnectionStrings.DefaultConnection = conf.GetSection("ConnectionStrings:DefaultConnection").Value;

			// aggiunto il servizio Singleton con Model Settings e parametri (sets)
			services.AddSingleton<Settings>(sets);
			
			//// Add others services
			//services.AddSingleton<Worker>();
		}
	}
}

Creazione del file Worker.cs e importazione dei parametri di configurazione attraverso i services

Arrivati a questo punto la preparazione base della lettura dei parametri nel progetto Console è terminata. Ora sarà sufficiente creare un nuovo file con relativo codice da avviare tramite gli appositi comandi che inseriremo nella pagina Program.cs.
Denomineremo il nuovo file Worker.cs come da figura:

All’interno di Worker.cs inseriremo il seguente codice:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TemplateConsoleProject.Model;

namespace TemplateConsoleProject
{
	public class Worker
	{
		private readonly Settings _sets;

		public Worker(Settings sets)
		{
			_sets = sets;
		}

		public Task DoWork()
		{
			return Task.Run( async () =>
			{
				Console.WriteLine("Nome: {0}", _sets.User.UserName);
				Console.WriteLine("Cognome: {0}", _sets.User.UserSurname);
				Console.WriteLine("Stringa di connessione al database: {0}", _sets.ConnectionStrings.DefaultConnection);

                                Console.WriteLine("Pres any key...");
				Console.ReadKey();
				await Task.CompletedTask;
			});
		}
	}
}

Nel file Program.cs si dovrà inserire il service Singleton Worker ed avviare la funzione DoWork in MainAsync. Il codice modificato in Program.cs è il seguente:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;
using TemplateConsoleProject.Model;

namespace TemplateConsoleProject
{
	class Program
	{
		static void Main(string[] args)
		{
			MainAsync(args).Wait();
		}
		static async Task MainAsync(string[] args)
		{
			// Istanziata la collezione di servizi 
			ServiceCollection serviceCollection = new ServiceCollection();
			ConfigureServices(serviceCollection);
			IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();

			try
			{
				await serviceProvider.GetService<Worker>().DoWork();
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private static void ConfigureServices(IServiceCollection services)
		{
			// Lettura del file appsetings.json
			IConfigurationRoot conf = new ConfigurationBuilder()
				.SetBasePath(Environment.CurrentDirectory)
				.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
				.Build();

			// passaggio dei parametri al Model Settings
			var sets = new Settings();
			sets.User = new User();
			sets.ConnectionStrings = new ConnectionStrings();
			sets.User.UserName = conf.GetSection("User:UserName").Value;
			sets.User.UserSurname = conf.GetSection("User:UserSurname").Value;
			sets.ConnectionStrings.DefaultConnection = conf.GetSection("ConnectionStrings:DefaultConnection").Value;

			// aggiunto il servizio Singleton con Model Settings e parametri (sets)
			services.AddSingleton<Settings>(sets);
			
			//// Add others services
			services.AddSingleton<Worker>();
		}
	}
}

Avvio del progetto e risultato finale

Una volta concluse le diverse procedure, si manderà in esecuzione il programma che è stato creato seguendo le indicazioni della guida in oggetto e si dovrà ottenere un risultato simile a quello della seguente figura: