Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

La mia classe Settings, finalmente

Una citazione da un grandissimo film degli anni '80 diceva:
"Strano gioco. L'unica mossa vincente è non giocare."
Chi indovina, vince un premio - non ho ancora deciso cos'è!

Mi è venuto in mente anche un buon mio amico/nostro collega, che invece di usare librerie pre-esistenti, preferiva cominciare da zero e farsele da sè. E' esattamente quello che alla fine ho deciso io per il mio problema riguardante i settings della mia applicazione HappySign. Ho creato una classe Settings che espone tutta una serie di membri che sono poi i settings che voglio usare nella mia applicazione. Ecco un piccolo estratto di codice:

public class Settings
{
    
public static string ConfigDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\HappySign";
    
public static string ConfigFile = @"\Settings.config";
    
public static string TemporaryFile = @"\Remember.tmp";

    
#region "Privati"
    private bool 
_TopMost;
    
private StartupPositionValues _StartupPosition;
    
private Color _BackColorStart;
    
private Color _BackColorEnd;
    
private Color _TitleForeColor;
    
private Color _TitleForeColorHot;
    
private Color _BackColorBar;
    
private Color _ForeColorItem;
    
private Color _ForeColorItemHot;
    
#endregion

Quelli elencati sopra sono i membri privati della classe: ovviamente ho creato anche i membri pubblici. Poi ho aggiunto due metodi:

public void LoadSettings()
{ }

public void WriteSettings()
{ }

che si occupano effettivamente di leggere e scrivere sul mio file di configurazione. Notare nel primo blocco di codice tre membri statici molto utili:

ConfigDirectory, che ritorna il path "C:\Documents and Settings\username\Application Data\HappySign".
ConfigFile, cablato dentro il codice, e che ritorna sempre "Settings.config".
TemporaryFile, cablato dentro il codice, e che ritorna sempre "Remember.tmp".

Quando istanzio un oggetto dalla classe Settings e chiamo il metodo LoadSettings, questo non fa altro che aprire il file "C:\Documents and Settings\username\Application Data\HappySign\Settings.config". La struttura del Settings.config è identica a quella di qualsiasi app.config. Nel mio caso è qualcosa di simile a questo:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <!--
        StartUpPosition = 1, centrato sullo schermo
        StartUpPosition = 2, allineato 
in alto a sinistra
        StartUpPosition = 3, allineato 
in alto a destra
        -->
    <
add key="StartUpPosition" value="3" />
    <
add key="TopMost" value="False" />
    <
add key="BackColorStart" value="Moccasin" />
    <
add key="BackColorEnd" value="LightSkyBlue" />
    <
add key="TitleForeColor" value="White" />
    <
add key="TitleForeColorHot" value="Yellow" />
    <
add key="BackColorBar" value="LightSteelBlue" />
    <
add key="ForeColorItem" value="Blue" />
    <
add key="ForeColorItemHot" value="Red" />
  </appSettings>
</configuration>

Questa sera predisporrò una piccola procedura di primo avvio, che si scatena quando non viene trovato il file Settings.config dentro la directory. In questo caso, ne propongo uno di default, che poi l'utente ha la facoltà di modificare come vuole tramite UI.

Qualche dettaglio su LoadSettings
Questo metodo è basato sul fatto che posso scandire tutti i ChildNodes del tag AppSettings. Nel file XML sopra, i ChildNodes sono 11, tante quante i settings che voglio leggere. Quindi, ho implementato un banale for...next e uno switch (purtroppo!): in base al valore di nodo.Attributes[0].Value, valorizzo il membro della classe Settings corrispondente.

int howmany = nodoAppSettings.ChildNodes.Count;

// parto da 1 così salto il primo tag che è solo un commento
for(int i=1; i<howmany;i++)
{
    nodo = nodoAppSettings.ChildNodes[i];
    key = nodo.Attributes[0].Value;
    
value = nodo.Attributes[1].Value;
    
switch(key)
    {
        
case "StartUpPosition":
            _StartupPosition = (StartupPositionValues) Convert.ToInt32(
value);
            
break;
        
case "TopMost":
            _TopMost = 
value == "True";
            
break;

eccetera, eccetera, eccetera...

E' un metodo che non mi piace, però adesso me lo tengo così. Avrei potuto usare una HashTable, una Collection o una struttura di questo tipo, così potevo caricare dinamicamente i valori contenuti in Settings.config, però perdevo l'enorme vantaggio di 1) Intellisense 2) Di conseguenza, leggibilità del codice 3) Strong-typed dei membri 4) Avrei dovuto farcire il codice - ovunque - di casting per convertire da object al tipo corretto in base al contesto. Avrei potuto popolare una HashTable, per esempio, con tutti i valori provenienti da XML, e che arrivano come string: il popolamento sarebbe avvenuto con un ciclo, ed aggiungendo un elemento per ogni tag <add> incontrato. Però - ripeto - alla fine mi sarei trovato un HashTable pieno di stringhe che andavano "castate" di volta in volta al tipo corretto. Chissà se mi sono spiegato?

Come al solito, per avere maggior controllo è sempre consigliabile farsi le cose da sè. Ovvio che magari non è il massimo delle performance, non è scalabile, non avrà un sacco di caratteristiche proprie delle library più quotate, ma almeno fa quello che dico io (e solo quello) e a me per adesso basta.

powered by IMHO 1.2

Print | posted on mercoledì 9 novembre 2005 15:29 |

Feedback

Gravatar

# re: La mia classe Settings, finalmente

> Come al solito, per avere maggior controllo è sempre consigliabile farsi le cose da sè. Ovvio che magari non è il massimo delle performance, non è scalabile, non avrà un sacco di caratteristiche proprie delle library più quotate, ma almeno fa quello che dico io (e solo quello) e a me per adesso basta.

Come al solito... per aver migliori risultati bisogna studiare... ;-)
E' inutile farsi le cose a mano se sai cosa c'è e dove usarlo...
Non si finisce mai di imparare!!!
09/11/2005 17:28 | Lorenzo Barbieri
Gravatar

# re: La mia classe Settings, finalmente

no... il problema è che non va bene... se c'è un modo giusto di fare le cose... lo si fa... o almeno... si cerca di farlo....



e non è un problema di microsoft che cambia gli attributi... non ci sono questo tipo di breaking changes...

ricordati che il blog di ugi è molto seguito, e se si scrive qualcosa, la gente poi lo fa... cerchiamo per quanto possibile di dare il buon esempio... che google ritrova tutto, anche le cose sbagliate...
09/11/2005 23:07 | Lorenzo Barbieri
Gravatar

# Come serializzare seriamente (gioco di parole) con .NET

10/11/2005 19:11 | Technology Experience
Gravatar

# Come serializzare seriamente (gioco di parole) con .NET

10/11/2005 19:16 | Technology Experience
Gravatar

# re: La mia classe Settings, finalmente

Rudy:
in mezzo a tutti questi post, mi sono dimenticato del tuo commento iniziale...
RISPOSTA ESATTA!!!!
HAI VINTO UN......boh.....
10/11/2005 19:50 | Igor Damiani
Gravatar

# re: La mia classe Settings, finalmente

urra ho vinto un bho... è la prima volta che vinco qualcosa grazie!!!
10/11/2005 23:39 | Rudy
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET