Nel web.config è possibile memorizzare informazioni utili per l'applicazione, informazioni che possiamo modificare in qualsiasi momento per le nostre personalizzazioni. Per esempio:
<configuration> <appSettings> <add key="background_color" value="#e0e0e0" /> </appSettings> </configuration>
Per leggere questa informazione da codice è sufficiente scrivere:
string colore=ConfigurationSettings.AppSettings["background_color"];
Questa tecnica porta in sé un grande problema: qualsiasi modifica fatta sul file "web.config" riavvia l'intera applicazione, con la conseguente perdita di tutte le informazioni legate all'AppDomain.
Una possibile soluzione è memorizzare i dati che vengono cambiati spesso in altri file e costruire una classe che legga queste informazioni. Questo comporta un primo problema prestazionale, visto che ad ogni richiesta di un'informazione presente in quel file dovremo leggere completamente il suo conteuto ed estrapolare l'informazione desiderata.
Per risolvere questo problema possiamo memorizzare in un oggetto shared/static o nella Cache dell'applicazione, per avere sempre quell'informazioni disponibile. Quest'ultima tecnica porta sì la soluzione del problema precedente, ma ne crea un altro: in caso di modifica del file dovremo avvertire in qualche modo l'applicazione di ripulire dalla cache i valori precedenti per prendere quelli nuovi.
Il .NET Framework, fin dalla versione 1.0, mette a disposizione la classe FileSystemWatcher, che permette di monitorare qualsiasi modifica a file o directory. Grazie a questa classe possiamo crearne una che risolva anche il secondo problema.
Innanzitutto vediamo il file di configurazione personalizzato, che chiameremo myConfig.xml e che inseriremo nella sotto directory "aspitalia" della root:
<?xml version="1.0" encoding="utf-8" ?> <aspitalia.com> <username>andrewz</username> <registered>30/10/2001</registered> </aspitalia.com>
All'interno sono presenti due semplici dati, uno username e una data.
Per leggere questi dati dalla nostra applicazioni creiamo una classe static che acceda a quel file:
using System; using System.IO; using System.Xml; /// <summary> /// Summary description for MyConfig /// </summary> public class MyConfig { private static FileSystemWatcher fwatch; static MyConfig() { xml = null; fwatch = new FileSystemWatcher(); fwatch.Filter = "myConfig.xml"; fwatch.Path = AppDomain.CurrentDomain.BaseDirectory + "aspitalia\\"; fwatch.IncludeSubdirectories = false; fwatch.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Attributes | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size; fwatch.Changed += new FileSystemEventHandler(ResetBuffer); fwatch.EnableRaisingEvents = true; } public static void ResetBuffer(object o, FileSystemEventArgs e) { xml = null; } // Public properties public static string UserName { get { return read("username"); } } public static DateTime Registered { get { return DateTime.Parse(read("registered")); } } // private methods private static XmlDataDocument xml; private static object o = new object(); private static string read(string parameter) { if (xml == null) { lock (o) { if (xml == null) { try { xml = new XmlDataDocument(); xml.Load(AppDomain.CurrentDomain.BaseDirectory + "aspitalia\\myConfig.xml"); } catch { throw new Exception("Error in 'myConfig.xml' file."); } } } } return xml.DocumentElement.SelectSingleNode("//aspitalia.com/"+parameter).InnerText; } }
Per leggere le informazioni sarà dunque sufficiente scrivere:
Response.Write(MyConfig.UserName); Response.Write(MyConfig.Registered.ToString());
All'interno della classe MyConfig è utilizzato l'oggetto FileSystemWatcher, nel quale viene impostato il percorso e il file da monitorare:
fwatch.Filter = "myConfig.xml"; fwatch.Path = AppDomain.CurrentDomain.BaseDirectory + "aspitalia\\";
In Filter possiamo specificare sia un nome specifico di file che più file con caratteri jolly. Se avessimo voluto monitorare tutti quelli con suffisso ".xml" avremmo dovuto scrivere "*.xml".
Con la riga successiva viene specificato che non devono essere incluse eventuali file in subdirectory (in caso in Filter vengono specificati più file con caratteri "jolly"):
fwatch.IncludeSubdirectories = false;
In NotifyFilter vengono specificate le opzioni per le modifiche ai file o alla directory.
Ora possiamo impostare l'evento che sarà avviato in caso una delle modifiche sopra impostate avvenga nei file specificati:
fwatch.Changed += new FileSystemEventHandler(ResetBuffer);
Infine viene avviato il controllo:
fwatch.EnableRaisingEvents = true;
Ora abbiamo un file di configurazione che possiamo modificare senza problemi di riavvio dell'applicazione o di errata memorizzazione dovuta alla Cache.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Migliorare la scalabilità di ASP.NET Core 7 grazie all'output cache
Definire la durata dell'output cache in ASP.NET Core 7
Sfruttare la local cache del browser tramite gli ETag in ASP.NET Core
Catturare la telemetria degli eventi di output cache in ASP.NET Core
Gestire la query string nell'output cache di ASP.NET Core
Sfruttare i tag nell'output cache di ASP.NET Core 7
Cache policy su route groups di Minimal API in ASP.NET Core 7
Definire le impostazioni di cache a livello di controller in ASP.NET Core 7
Taggare la output cache in base al routing in ASP.NET Core
Sfruttare l'output cache di ASP.NET Core 7 con i controller
I più letti di oggi
- Evitare la command injection in un workflow di GitHub
- Utilizzare i default interface method per aggiornare le interfacce in C# 8
- Speciale Mastering Entity Framework
- ASP.NET MVC 3 al download in RTM
- MIX 2011: Tutte le novità dei tool di ASP.NET MVC 3
- Uno sguardo a ASP.NET 4.5 e Visual Web Developer 11
- Microsoft lancia il nuovo Windows Phone Dev Center, sostituendo l'AppHub