Allora, l'avevo promesso, vediamo quanto riesco a mantenere l'impegno preso nel scrivere una serie di post su alcuni aspetti, soprattutto architetturali, che abbiamo scelto di utilizzare in ModelVirtualCasting (ModelVC per gli amici).
L'argomento di cui vorrei parlarvi stasera è il modello di accesso ai dati che abbiamo scelto di utilizzare. Immagino che abbiate capito che ModelVC usi internamente ADO.NET Entity Framework, sebbene questo non sia esposto direttamente agli strati sovrastanti, che invece hanno la possibilità di accedere alla base dati tramite degli oggetti chiamati Repository.
Cos'è un repository e soprattutto, perché questa scelta? In due parole, un repository è un oggetto che si frappone tra noi e lo strato di accesso ai dati, comportandosi come se fosse una normale collection .NET, supportando quindi aggiunte e rimozioni di oggetti, e sul quale possiamo eseguire query (ad esempio tramite LINQ) come se i dati si trovassero già tutti in memoria. Ottimo, ma allora sono simili agli ObjectSet di Entity Framework, che bisogno abbiamo di scrivere questo codice in più? Vediamo un attimo la struttura delle interfacce:
Come vedete, questa architettura mi consente un livello di personalizzazione che con gli ObjectSet non ho, ossia:
- Avere a disposizione due interfacce base, IReadOnlyRepository e IRepository, ci consente di forzare in sola lettura alcune entità, che by design immaginiamo non dovranno mai essere inserite o eliminate;
- Possiamo esporre metodi personalizzati per un repository specifico, quando questo può risultare comodo, come nel caso di GetByUsername su IUserRepository
- Possiamo personalizzare il comportamento in fase di Add, ad esempio effettuando su UserRepository un override del metodo InsertOnSubmit e verificare al suo interno che l'email dell'utente che stiamo inserendo non sia già presente nel database.
Il tutto senza rinunciare alle potenzialità di Linq To Entities, visto che i nostri Repository agiscono come wrapper proprio di ObjectSet e che metodi come Where e GetAll restituiscono una IQueryable<T>, così che possiamo tranquillamente scrivere qualcosa tipo
var query = myUserRepository .Where(u => u.Username == u.Password) .Select(u => new { Nick = u.Username, Email = u.Email } );
e star sicuri che l'expression tree generato verrà dato in pasto all'engine di EF e tradotto in una query SQL verso il database.
Ultimo e fondamentale vantaggio, avere questa struttura basata su interfacce ci consente di disaccoppiare gli strati superiori (servizi o UI) da una particolare implementazione, che può essere invece scelta a runtime, così che l'indomani possiamo realizzare un set di repository basati su una tecnologia completamente diversa (mah.. questa affermazione mi è sempre sembrata un po' fuffosa, sarò sincero con voi :D) o soprattutto:
- Semplificarci la vita in fase di test, visto che un IUserRepository è infinitamente più facile da mockare rispetto a EntityFrameworkContext.Users (brrr...); questo è un punto a favore importantissimo, dato che IObjectSet<T> già esposta da EntityFramework in realtà non espone tutte le logiche necessarie a gestire con efficacia un ObjectSet perché mancano parecchie robe fondamentali;
- Possiamo realizzare dei FakeRepository (li trovate in ASPItalia.ModelVirtualCasting.Fake) per testare la nostra applicazione su dati cablati nel codice, senza scomodare il database, consentendoci quindi a tutti gli effetti di parallelizzare alla grande il lavoro; per esempio, io sono riuscito a sviluppare parte dell'interfaccia utente quando Stefano ancora non aveva sviluppato nessun repository concreto, quindi con lo strato dati praticamante inesistente! E vi assicuro che, quando Stefano ha completato il suo lavoro, non ho dovuto cambiare nulla della UI per adeguarmi, solo una serie di impostazioni sul web.config.
Bene, con questa vi saluto e, sperando che vi interessi, vi do appuntamento ai prossimi post, nei quali ci addentreremo un po' nei meandri di questi oggetti per scoprire più nel dettaglio come sono fatti e come riusciamo ad istanziarli!
Ciao!
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
- Nuova versione per EF Mapping Verifier, il 30 settembre 2009 alle 20:01
- Testare il mapping di Entity Framework, il 17 settembre 2009 alle 09:00
- Basta! Italia 2009 - I'll be there!, il 13 marzo 2009 alle 17:01
- Gli ORM e la many to one: 3 approcci differenti, il 13 gennaio 2009 alle 18:01
- Alcune info per chi usa NHibernate, il 6 ottobre 2008 alle 08:34