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
Short-circuiting della Pipeline in ASP.NET Core
Implementare il throttling in ASP.NET Core
Effettuare lo stream della risposta in ASP.NET Core tramite IAsyncEnumerable
Mascherare l'output di un valore all'interno dei log di un workflow di GitHub
Generare file PDF da Blazor WebAssembly con iText
Recuperare un elemento inserito nella cache del browser tramite API JavaScript
Evitare la command injection in un workflow di GitHub
Utilizzare il trigger SQL con le Azure Function
Applicare il versioning ai nostri endpoint ASP.NET Core Minimal API
Miglioramenti nelle performance di Angular 16
Implementare l'infinite scroll con QuickGrid in Blazor Server
Creazione di plugin per Tailwind CSS: espandere le funzionalità del framework dinamicamente