La gestione della configurazione in ASP.NET Core è divenuta parecchio più avanzata rispetto a quanto accadeva in ASP.NET classico. Al di là della maggiore espressività dei file json, c'è anche una migliore gestione del reload dei dati di configurazione senza che questo provochi un ricilo dell'applicazione stessa.
In questo e nel corso dei prossimi script, vedremo alcuni esempi su come gestire queste modifiche, iniziando dalla tecnica più basilare di tutte, ossia utilizzando direttamente il servizio IConfiguration.
Immaginiamo allora di avere impostato una chiave di configurazione myValue su appsettings.json:
{ "Logging": { ... }, "myValue": "value1" }
Per visualizzare la chiave letta, useremo un controller al quale abbiamo iniettato direttamente IConfiguration:
[Route("[controller]")] [ApiController] public class ConfigDemoController : ControllerBase { private static DateTime _timestamp = DateTime.Now; private IConfiguration _config; public ConfigDemoController(IConfiguration config) { _config = config; } [HttpGet] public string Get() { return $"{_timestamp}: {_config.GetValue<string>("myValue")}"; } }
Il controller ha anche un timestamp static, che pertanto viene inizializzato una sola volta per ciclo di vita dell'applicazione, e possiamo utilizzare per verificare se sia avvenuto un riciclo.
Come possiamo sperimentare, ogni volta che invochiamo questo controller, il timestamp resterà il medesimo, ma se variamo il valore su appsettings.json, il controller mostrerà il valore più aggiornato.
Questo è possibile grazie al fatto che IConfiguration istanzia interamente un FileSystemWatcher che monitora i file di configurazione e solleva un evento nel caso in cui vengano modificati, provocando una rilettura della configurazione stessa. In altri termini, IConfiguration esporrà sempre la configurazione più recente, evitando allo stesso tempo di leggere continuamente su FileSystem.
Se invece che in un controller dobbiamo passare questi dati a un servizio, dobbiamo tenere conto del fatto che la classe Startup verrà eseguita solo all'avvio dell'applicazione. Pertanto, se passassimo il valore di configurazione in maniera statica come nell'esempio in basso, perderemmo il beneficio del refresh che abbiamo visto finora:
public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // così leggiamo il valore una sola volta e ignoreremo tutti gli aggiornamenti var value = Configuration.GetValue<string>("myValue"); services.AddTransient<MyService>(sp => new MyService(value)); }
Il modo corretto è di sfruttare invece il ServiceProvider passato nella lambda, per recuperare l'istanza di IConfiguration da cui leggere il setting:
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddTransient(sp => { var config = sp.GetRequiredService<IConfiguration>(); return new MyService(config.GetValue<string>("myValue")); }); }
Come detto all'inizio dello script, questo è il modo più basilare e semplice per leggere la configurazione più aggiornata, ma non è esente da difetti: per esempio, può risultare complesso far sì che tutti i componenti di una richiesta leggano lo stesso valore, se la modifica avviene concorrentemente all'esecuzione della richiesta stessa. Oppure, effettuare il refresh dei setting in una classe registrata come singleton.
Di questi aspetti ci occuperemo nei prossimi script.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Effettuare lo stream della risposta in ASP.NET Core tramite IAsyncEnumerable
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Utilizzare domini personalizzati gestiti automaticamente con Azure Container Apps
Disabilitare automaticamente un workflow di GitHub (parte 2)
Short-circuiting della Pipeline in ASP.NET Core
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Utilizzare i primary constructor in C#
Creare moduli CSS in React
Ottenere il contenuto di una cartella FTP con la libreria FluentFTP
Usare il versioning con i controller di ASP.NET Core Web API
Evitare la command injection in un workflow di GitHub
Registrare servizi multipli tramite chiavi in ASP.NET Core 8
I più letti di oggi
- Paginare i risultati con QuickGrid in Blazor
- Eliminare una determinata proprietà da un oggetto JavaScript
- Utilizzare il trigger SQL con le Azure Function
- Low code e pro code: come estendere Power Platform con .NET e Visual Studio
- Modernizzare le applicazioni WPF e Windows Forms con Blazor
- Q# for Quantum Programming, an "only for the brave" session