Da qualche tempo sono tornato a sperimentare con l’Entity Framework. Nonostante prima Silverlight e recentemente le applicazioni Windows Phone e Windows Store mi stiano impegnando parecchio, soprattutto dal punto di vista della User Interface, mi capita molto spesso di avere a che fare con le problematiche di backend e architetturali. In questo post e nei prossimi vorrei mostrarvi una soluzione che ho adottato tempo fa con Entity Framework e sulla quale non ho mai avuto tempo di scrivere approfonditamente, ma che recentemente ho provato anche con EF5.0 scoprendo che è perfettamente applicabile.

Nel primo post vorrei dimostrarvi come sia possibile, con pochi e semplici passi, spostare le entità generate a partire dall’EDMX in un assembly separato. Usare Entity Framework ci regala un sistema di generazione del codice davvero potente, ma spesso ci fa scordare le buone pratiche e il rischio di mischiare le cose è sempre dietro l’angolo. Dal mio punto di vista, una volta scelto che le entità debbono essere POCO (cioè oggetti leggeri che non hanno dipendenze) la scelta di spostarle in un assembly dedicato è praticamente imprescindibile, non fosse altro che per mantenere ordine. Ecco quindi come procedere con EF5.0.

imageDiamo per scontato di aver generato una solution simile a quella riportata nella figura qui a lato. Il primo progetto "Data" è quello che conterrà il DataContext mentre il secondo progetto, denominato "Entities" servirà a contenere le entità generate da Entity Framework. L'unica accortezza preliminare è quella di creare un riferimento da "Data" a "Entities" dato che come intuibile la parte che rimane nel primo assmbly dovrà referenziare le entità. Come secondo passo è il momento di generare un EDMX, all'interno del progetto "Data", usando il template di Visual Studio 2012 (ma funziona anche con il 2010). Lascio a voi la scelta del database, basta che alla fine vi troviate con almeno una entità generata come riportato nella figura sottostante.

imageCon Entity Framework 5.0 il template automaticamente seleziona per noi una modalità di generazione del codice "DbContext", cioè delle entità che sono del tutto "pulite" da ogni riferimento a qualsivoglia classe base. Se infatti si apre il file "Person.cs", generato a partire dalla tabella "People" (sì, avete capito bene, People è plurale di Person e quindi il designer sceglie una entità del nome opportuno) vedrete che contiene esclusivamente le proprietà derivanti dalle colonne del database e null'altro.

Un'altra caratteristica di EF5.0 è che implicitamente installa I file .tt (template t4) che generano il codice ma questi file sono a nostra disposizione per eventualmente customizzare come il codice viene generato. Samples.Context.tt genera il DbContext mentre Samples.tt genera tutte le entità necessarie.

Ora, se si apre la cartella dei file del progetto "Data" e si prende il file Samples.tt, è possibile copiarlo nell'assembly "Entities". Questa operazione va fatta dal filesystem perchè Visual Studio non ci consente il cut & paste su questo item. Ma se poi, una volta copiato il file torniamo nel progetto "Data" ci sarà consentito di cancellare il file "Samples.tt". imageSulla sinistra riporto come appare il progetto dopo l'operazione.

Se si prova a compilare però ci si rende subito conto che la generazione delle entità fallisce con un errore. Il fatto è che il file TT che abbiamo spostato contiene un riferimento al file EDMX dal quale estrae le informazioni che gli servono per generare le entità. Avendo spostato il file dobbiamo correggere questa referenza e per farlo occorre modificare manualmente il file Samples.tt.

Modificare un file TT non è la cosa più semplice e intuitiva. Tanto per cominciare il codice non appare colorato e quindi pare di essere tornati a "emacs". In secondo luogo nemmeno l'intellisense ci viene in aiuto. L'unico sistema è quello "empirico" per cui si modifica e si genera provando a vedere se il risultato ottenuto è quello atteso. Solo in Visual Studio 2012 abbiamo un ottimo "Debugger" per I file TT che ci viene in aiuto quando proprio non ne veniamo fuori. Se proprio ne avete bisogno, potete scaricare l'ottimo "Tangible T4 editor" dalle estensioni di Visual Studio e sarete graziati da un editor decente. A questo punto, aprendo il file "Samples.tt" vedrete quanto segue nelle prime righe del file:

image

In particolare la linea che ci interessa è quella evidenziata. In questa riga dovremo riportare un path relativo cosicchè anche spostando il progetto in un'altra cartella esso sarà perfettamente compilabile. Nel mio caso il path è il seguente:

   1: const string inputFile = @"..\Elite.Samples.Architecture.Data\Samples.edmx";

Una volta modificata la linea e salvato il file Visual Studio ci mostrerà immediatamente i file delle entità generate diligentemente. Ma se si prova a compilare ci si scontra con un nuovo errore. L'errore è facilmente comprensibile: al DbContext generato nell'assembly "Data" mancano i riferimenti all'assembly delle entità. Non si tratta della referenza di progetto che dovremmo aver già creato ma banalmente dello "using". Apriamo quindi il file Samples.Context.tt, troviamo la riga dove appare "using System.Data.Entity.Infrastructure;" e aggiungiamo subito sotto le using all'assembly delle nostre entità. Nel mi caso "using Elite.Samples.Architecture.Entities;". In questo modo:

   1: using System;
   2: using System.Data.Entity;
   3: using System.Data.Entity.Infrastructure;
   4: using Elite.Samples.Architecture.Entities;

A questo punto il compilatore non si lamenta più. Due semplici modifiche ai template di generazione e ci ritroviamo DbContext ed entità in asembly separati, che compilano alla perfezione. Esattamente quello che stavamo cercando. Per I più pigri ecco il progetto ottenuto dai passi che vi ho riportato. Ricordate solo di modificare la password nel file di configurazione, laddove trovate YOURPASSWORDHERE. Poi tenetelo da parte per il prossimo post...

Download: Elite.Samples.Architecture.zip (2,32MB)


Aggiungi Commento