Gestire più files di configurazione con Visual Studio 2010 e XDT (Xml Data Trasformation)

Appena si crea una nuova Web Application con Visual Studio 2010 la prima cosa che salta all’occhio è l’icona a forma di triangolo posta accanto al web.config, che fa intuire la presenza di alcune voci legate allo stesso; di fatto l’immagine seguente mostra altri due files di configurazione oltre a quello principale:

001

Per noi sviluppatori i files di configurazione rappresentano sempre una parte un po’ ostica, in quanto portano via tempo nella preparazione tra i diversi ambienti con cui siamo “costretti” a lavorare quotidianamente. Normalmente un’applicazione web vive su tre ambienti ben distinti, dove ognuno di questi avrà differenti stringhe di connessione e diversi parametri:

  • Ambiente di sviluppo;
  • Ambiente di test;
  • Ambiente di produzione;

Ovviamente questo numero può variare da applicazione ad applicazione, ma resta il fatto che ad ogni deploy è necessario cambiare la configurazione; oltre ciò, se i files di configurazione in questione sono particolarmente corposi e complessi si aggiunge anche un costo di gestione non indifferente, aumentando inoltre il rischio di errori.
Per capire meglio uno scenario come quello descritto precedentemente, si provi ad immaginare un file di configurazione di un’applicazione web che ha centinaia di parametri, custom section, endpoint, stringhe di connessione, ecc: è pazzesco modificare manualmente ogni file di configurazione.

Fortunatamente con questa nuova release ci viene offerta la possibilità di rendere indolore la gestione di più ambienti grazie all’XDT (Xml Data Trasformation)  ma, per capire bene come sfruttarla, è necessario capire a cosa servono i differenti files e dove andare ad inserire le nostre informazioni.

Il file web.config, quello classico per intenderci, conterrà tutte le informazioni necessarie alla costruzione della configurazione finale, sia che queste informazioni siano uguali per tutti gli ambienti sia che debbano variare.

Sotto il web.config sono presenti due files, Web.Debug.config e Web.Release.config, che hanno il compito di contenere le informazioni che cambiano da ambiente ad ambiente; normalmente i due files creati dovrebbero corrispondere all’ambiente di sviluppo e all’ambiente di produzione, rispettivamente Debug e Release, ma è possibile specificare altri ambienti in base alle proprie esigenze tramite apposite voci, come mostrato dalla sequenza sottostante:

002 003 004 005 006

Nell’esempio seguente verrà mostrato un file di configurazione la cui stringa di connessione è differente tra i tre ambienti, Debug, Release e Test.

Come prima cosa è necessario aggiungere al file web.config l’apposita voce nella sezione connectionStrings, come mostrato di seguito:


  

La stringa presente in questo file coincide con quella dell’ambiente di debug e verrà sostituita da Visual Studio in fase di deploy ma, per far ciò, è necessario andare ad inserire il valore corretto nei restanti files di configurazione, come mostrato di seguito:

    

  


    

    



    

    

Il codice è piuttosto semplice, sono presenti due nuovi attributi xdt:Transform e xdt:Locator, dove xdt significa Xml Data Trasformation;  il primo attributo indica cosa deve essere sostituito (in questo esempio tutti gli attributi), mentre il secondo indica la regola di Matching (in questo esempio il replace viene effettuato nel caso in cui l’attributo “name” coincida tra i files di configurazione).

Ovviamente il numero di operazioni e condizioni disponibili va ben oltre il SetAttributes ed il Match; si ha infatti a disposizione un ricco set di operatori e trasformazioni che permettono di effettuare operazioni piuttosto complesse. Di seguito l’elenco degli operatori ed operazioni utilizzabili:

Operatori:

  • Match – indica che la trasformazione avviene soltanto quando l’attributo inserito all’interno dell’operatore coincide, come mostrato nel nostro esempio;
  • Condition – molto simile alla condizione if, viene utilizzato per specificare i casi in cui la trasformazione deve avvenire (es: xdt:Locator="Condition(@name=’Northwind or @providerName=' System.Data.SqlClient')" );
  • XPath – la sezione da trasformare viene identificata tramite una query XPath(es: xdt:Transform="Replace" xdt:Locator="XPath(//system.web)");

Trasformazioni diponibili:

Replace Effettua il replace dell’intero nodo

<assemblies xdt:transform="Replace">
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"> </add>
</assemblies>

Remove Rimuove il nodo dal file di configurazione corrente

<assemblies xdt:transform="Remove"></assemblies>

RemoveAll Rimuove tutti i nodi all’interno della sezione

<connectionstrings>
<add xdt:transform="RemoveAll"> </add>
</connectionstrings>

Insert Aggiunge un nuovo elemento alla sezione

<authorization>
<deny users="*" xdt:transform="Insert"></deny>
</authorization>

SetAttributes Reimposta gli attributi specificati tra parentesi, separati dalla virgola; in caso di omissione degli attributi vengono sostituiti tutti.

<compilation batch="false"  xdt:Transform="SetAttributes(batch)"> </compilation>

RemoveAttributes Rimuove gli attributi specificati tra parentesi, separati dalla virgola; in caso di omissione degli attributi vengono rimossi tutti.

<compilation xdt:transform="RemoveAttributes(debug,batch)"> </compilation>

InsertAfter Inserisce l’elemento dopo di un altro elemento tramite l’utilizzo di XPath;

InsertBefore Inserisce l’elemento prima di un altro elemento tramite l’utilizzo di XPath;

<authorization>
<allow roles=" Admins" xdt:transform="InsertBefore(/configuration/system.web/authorization/ deny[@users='*'])"></allow>
</authorization>

XSLT Effettua la trasformazione tramite un file XSLT

<appsettings xdt:transform="XSLT(V:\MyProject\appSettings.xslt)"></appsettings>

Per poter provare la trasformazione è necessario effettuare un deploy dell’applicazione cambiando l’ambiente di destinazione, come mostrato dalla sequenza seguente:

007 008 009 010 011

Devo ammettere che l’idea è fantastica e ben implementata, l’unico neo che ho trovato è che, in fase di debug tramite Visual Studio, cambiando l’ambiente di stage tramite l'apposito menu a tendina,  non viene effettuata la trasformazione mandando in play l’applicazione, e questo riduce il raggio di utilizzo della trasformazione alla singola fase di deploy.

Enjoy VS2010!


Comments