Utilizzare file di configurazione personalizzati con ASP.NET

di Andrea Zani, in ASP.NET 2.0, web.config,

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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi