Negli scorsi script (https://www.aspitalia.com/script/1403/Reagire-Modifiche-Configurazione-ASP.NET-Core.aspx e https://www.aspitalia.com/script/1404/Usare-Option-Pattern-Gestire-Configurazione-ASP.NET-Core.aspx) ci siamo occupati del refresh della configurazione in ASP.NET Core, e abbiamo analizzato sostanzialmente tre differenti opzioni:
- Iniettare IConfiguration direttamente: questo oggetto (almeno nel setup di default dei progetti ASP.NET Core) monitora il file appsettings.json e, nel caso di modifica, ne rilegge il contenuto. In questo modo possiamo essere sicuri di rileggere sempre i valori aggiornati, seppure in maniera non tipizzata e con uso di stringhe;
- definire un oggetto TOptions che rappresenti la nostra configurazione - o una sua parte - e iniettare IOptions
, nel caso non siamo interessati a rileggere i settings se dovessero essere modificati; - effettuare gli stessi passaggi del punto precedente, ma questa volta iniettare un'istanza di IOptionsSnapshot
in questo modo riceveremo ogni volta i dati aggiornati al momento dell'inizio della richiesta.
Un problema di IOptionsSnapshot è che, per definizione, è registrato come Scoped, e pertanto possiamo utilizzarlo come dipendenza solo per servizi a loro volta Transient o Scoped.
Quando invece abbiamo un servizio Singleton, del quale vogliamo aggiornare i setting se dovessero cambiare, dobbiamo invece sfruttare una terza interfaccia, chiamata IOptionsMonitor.
Immaginiamo allora di avere un servizio MyService che registreremo come Singleton:
public void ConfigureServices(IServiceCollection services) { // ... altro codice qui ... services.AddSingleton<MyService>(); services.Configure<ValueOption>(Configuration.GetSection("option")); }
Come possiamo notare, abbiamo anche configurato il nostro ValueOption in maniera del tutto analoga a quella degli esempi visti nello script precedente.
Dato che MyService è Singleton, possiamo iniettare un'istanza di ValueOption tramite IOptionsMonitor:
public class MyService { private DateTime _timestamp = DateTime.Now; private ValueOption _option; public MyService(IOptionsMonitor<ValueOption> option) { _option = option.CurrentValue; option.OnChange(newValue => _option = newValue); } public string GetString() { return $"{_timestamp}: {_option.MyStringValue}"; } }
Nel servizio abbiamo innanzi tutto salvato il valore corrente di ValueOption al momento della creazione dell'istanza di MyService. Successivamente, abbiamo registrato un handler per l'evento OnChange che, in presenza di una modifica ad appsettings.json, effettuerà il refresh del field _option con i nuovi valori.
Questo è un sistema molto elegante per poter mantenere la configurazione di MyService aggiornata pur continuando ad accedervi in maniera tipizzata.
Un'ultima nota riguarda il fatto che, data la natura asincrona del refresh, questo potrebbe avvenire in ogni momento, anche in concomitanza con l'esecuzione di un metodo. Quindi dobbiamo tenerne conto se accediamo alle option più volte all'interno dello stesso metodo, e vogliamo garantire che abbiano sempre lo stesso valore in quel contesto di esecuzione:
public void DoSomething() { var currentOption = _option; DoSomethingWithValue(currentOption.MyStringValue); // .. altro codice qui .. DoSomethingElseWithValue(currentOption.MyStringValue); }
Se accedessimo direttamente al field _option, invece, potrebbe accadere che DoSomethingWithValue e DoSomethingElseWithValue leggano diversi valori in presenza di race condition.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Creazione di plugin per Tailwind CSS: espandere le Funzionalità del Framework
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Reactive form tipizzati con modellazione del FormBuilder in Angular
Load test di ASP.NET Core con k6
Gestire i dati con Azure Cosmos DB Data Explorer
Miglioramenti nell'accessibilità con Angular CDK
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Aggiungere interattività lato server in Blazor 8
Supportare il sorting di dati tabellari in Blazor con QuickGrid
Ottimizzare la latenza in Blazor 8 tramite InteractiveAuto render mode
Filtering sulle colonne in una QuickGrid di Blazor
I più letti di oggi
- anche domani dalle 17:30 seguite con noi live #build15 https://aspit.co/build15
- Webcast 'AJAX & ATLAS Overview'
- a #igds il 25 e 26/10 a Milano puoi sviluppare un gioco per #wp8 con @AppCampus. in palio 70.000 Euro: https://aspit.co/apa
- WinJS in Windows Phone 8.1
- la RC di #vs13 è compatibile con #win81 RTM, non con la Preview. l'annuncio ufficiale è su https://aspit.co/any
- Ancora un bug: esce Mono 0.23
- SSL Certificates for everyone on Azure
- Mostrare una MessageBox con un custom control
- disponibile la preview 1 ci #dotnetcore 2.1, #aspnetcore, #efcore. performance, novità e migliorie su https://aspit.co/bmf
- si continua a #netconfit con 'developing modern web apps with #aspnetcore', con il nostro @dbochicchiohttps://aspit.co/netconf-18