in

DotNetMarche

.NET Framework User Group delle Marche

This Blog

Syndication

ExternalBlogs

Preoccuparsi di POCO

Ho appena letto un paio di post, uno di Andrea ed uno di Raf, sul domain model e sulla effettiva necessità di un dominio non solo "persistence ignorant" ma infrastructure ignorant. Decisamente poter creare un dominio infrastructure ignorant è una sfida interessante, e non posso che dire di essere daccordo con Andrea. D'altra parte come Raf fa notare, pensare di usare proxy potrebbe essere veramente dannoso per le prestazioni.

Personalmente non vorrei preoccuparmi a priori delle prestazioni, a parte il "premature optimization is the root of all evil", preferisco avere una architettura più manutenibile, e tenere sotto controllo le prestazioni durante lo sviluppo per capire se le soluzioni adottate siano in linea con i requisiti. La generazione di proxy a runtime può essere interessante (ci ho lavorato e la reflection.emit è decisamente divertente), ma a mio avviso non è adatta per questo genere di cose, si è vero, posso generare un proxy che supporti INotify... e quello che mi pare, ma poi è una classe che a design time non esiste,  non posso interagirci, etc etc.

Un approccio decisamente migliore è la generazione del codice design time, un po come il dataset Strongly typed. In questo modo ad esempio si potrebbe scrivere un generatore di DTO a partire dagli oggetti di dominio. L'approccio dei DTO è infatti quello che preferisco, anche perchè è possibile in questo modo ridurre i dati da trasmettere. Se ho un oggetto con 10 proprietà e mi serve una lista di tali oggetti da mostrare su una griglia che binda solo 3 proprietà su 10, avere un DTO specializzato allo scopo è sicuramente la cosa migliore.

Il problema dei Dto è naturalmente che: se li gestisci a mano, puoi farlo per un dominio di poche entità, altrimenti diventi matto, se usi un generatore, questo deve essere il più possibile automatizzato. A suo tempo pensai ad esempio ad usare codesmith, ma c'è bisogno di qualche cosa di più efficiente. La cosa migliore sarebbe avere un designer simile a quello delle classi o dei dataset strongly typed, potere fare drag and drop di classi, decidere quali proprietà spostare e generare tutto il codice a design time, magari utilizzando anche delle partial property per potersi intrufolare in mezzo al codice generato se possibile. Il problema maggiore di un approccio fortemente DTO oriented è che, come dice raf

Il costo di creazione e manutenzione dei proxy e del codice che serve a fare quelle stesse cose (ma dall'esterno dell'entity) non è poco: maggiore complessità e ciclo di vita più lungo del software

Però in certi casi sono cose che tolleriamo senza problemi, il lazy load NHibernate lo fa con Castle.DynamicProxy (Nhibernate 2.0 dovrebbe essere portato a DynamicProxy2) ed è una cosa che non ha mai sollevato troppe obiezioni. D'altra parte ci fidiamo del fatto che il generatore di codice sia corretto, per cui l'unica manutenzione è al massimo quella di mantenere i file di mapping o qualsiasi artefatto sia stato creato per stabilire come il codice debba essere generato.

Il problema di fondo è che raggiungere la completa ignoranza dell'infrastruttura è sicuramente utopico e forse anche troppo radicale, quello che vorrei è solamente poter limitare al minimo questa intrusione. NHibernate riesce a fare persistenza richiedendo poche specifiche alle nostre classi (membri virtuali per i proxy, un costrutture di default, ..), per cui è sicuramente possibile fare librerie di infrastruttura poco intrusive ;). Mi piacerebbe che quando qualcuno progetta infrastrutture cercasse di realizzarle nel modo meno intrusivo per le entità di dominio, se poi questo non è possibile bene, ma almeno provare.

Il rischio è che ci si trovi ad avere la classe X che implementa 10 interfacce solo per il piacere di essere usata da EntityFramework, Reporting Services, Crap Library, bla bla.

alk.

Read the complete post at http://feeds.feedburner.com/~r/alkampfer/~3/351503359/93587.aspx

Powered by Community Server (Commercial Edition), by Telligent Systems