Non posso che concordare sul discorso Persistence Ignorance fatto pìù volte da Andrea sull'entity framework.
Con altrettanta convinzione affermo però che la completa ignoranza dall'infrastruttura è utopica in scenari reali:
- INotifiyPropertyChanged / INotifiyPropertyChanging ha un costo neppure tanto basso quando è implementato negli oggetti a causa del raising degli eventi. Nella RafCollection avevo scritto INotifiyPropertyChanging ben prima che il framework la introducesse ma sono tornato indietro sfruttando la INotifiyPropertyChanged con parametro null per motivi di performance.
Se penso di usare addirittura un proxy, i valori di performance si alzano vertiginosamente.
- IEditableObject è inerentemente compito dell'entity in quanto gestisce la transazionalità dello stato dell'entity stessa. Questa interfaccia garantisce la coerenza dello stato dell'oggetto quando vengono effettuate modifiche a più proprietà.
- Cloning. Nessuna interfaccia qui per il noto articolo di Brad Abrams. Ma non c'è dubbio che il clone di un oggetto è molto più efficiente se fatto su membri *privati*.
Esempio: Il datetime mantiene un intero a 64 bit. Se io per clonarlo copio tutte le proprietà (giorno, mese, anno, ...) invece di duplicare il valore a 64 bit sto facendo un pessimo lavoro.
Ricordiamoci che non tutte le entity sono fatte di fields 1:1 con le proprietà e una strategia come POCO la si implementa per tutte le entity o nessuna.
- ISerializable / IXmlSerializable. E qui faccio veramente fatica a vedere un proxy che possa risolvermi questa situazione in modo anche lontanamente decente. Il serializzatore Xml tra le altre cose genera al volo con CodeDom il codice per generare una serializzazione performante.
Io mi sono scritto un serializzatore Xml che fa le stesse cose di quello standard ma le performance sono ben lontane da quelle ottenute grazie a CodeDom.
Poi arriviamo a motivazioni più pratiche. 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.
BTW, come ho detto ai Community Days, mi stupisce che i framework IoC e il neonato MEF lavorino ancora così tanto di reflection invece di sana generazione di codice adhoc a *design* time.
E una volta che fosse possibile trovare il compromesso e arrivare finalmente ad una totale agnosticità del domain model, che ci guadagno? È tutto scritto in C#, dipende tutto dal framework, da un CLR all'altro certe classi potrebbero diventare obsolete, ...
Insomma *IMHO* bisogna arrendersi al fatto che tutto quello che scriviamo è legato alla tecnologie che usa. Questo non toglie che questo vincolo possa permetterci il cross-platform (vedi Mono) ma non certo l'universalità.
Urka, una volta che non sono daccordo con Il Presidente, adesso rischio dei perdere i gradi 
L'ingresso di Linq nel Framework è stato prepotente. I tangibili vantaggi di Linq to Sql e le promesse delle future versioni di Entity Framework hanno scatenato una vera e propria corsa a Linq. E pensare che siamo solo alle prove tecniche di trasmissione dei concetti di programmazione funzionale dentro il Framework ...
Mi è saltata in mente un'idea balzana. Ma voglio prima partire riaffermando alcuni concetti ormai consolidati da case studies e libri di fama:
- Le architetture multilayer sono più facili da difendere (sicurezza applicativa)
- L'astrazione con provider è un vantaggio in termini di evoluzione dell'applicazione e di manutenibilità
- I servizi (stateless) garantiscono un alto margine di scalabilità
Vediamo come sfruttare la programmazione funzionale in una architettura multilayer. Per esempio la UI:
- tipicamente esegue molte operazioni di selezione di entità caratterizzate da un certo numero di proprietà [projection]
- ha la necessità di filtrare i risultati [restriction]
- spesso deve paginare i risultati perché sono comunque troppi [partitioning]
- deve anche ordinare i risultati secondo un criterio [ordering]
- può avere bisogno di raggruppare [grouping] o di aggregare (sum, count, max, ...) [aggregation]
- ...
Tutto questo ricorda molto gli operatori di Linq 
Il service layer da parte sua espone già un contratto che permette una astrazione rispetto il data server o comunque le risorse sottostanti. Ma la difficoltà sta proprio nel contratto che il più delle volte è "ad hoc" per la nostra applicazione. Un domani che dovessimo usare un contratto differente, dovremmo necessariamente applicare una di queste soluzioni: (a) cambiare la UI per supportare il nuovo servizio, (b) creare un nuovo servizio che "trasformi" i dati con il nostro formato, (c) usare BizTalk per piallare le differenze.
L'idea balzana è semplice:
- usare i provider di Linq come "adapter" per lo strato dei servizi
- i provider useranno gli expression tree (che sono serializzabili) come "linguaggio" per mappare le richieste della UI sul servizio (Expression.Call esegue un determinato metodo)
- Le Expression.Call possono essere usate anche per le operazioni che non facciano mero retrieval di valori (per esempio insert/update/delete)
- usare sempre gli expression tree per le restriction (And, Not, Or, etc.). [Questo non esclude di poter avere oggetti di business differenti nel presentation e nel service layer in quanto convertire un expression tree non è complesso.]
- ...
Il vantaggio immediato è quello di ottenere un presentation veramente sterile, persino dai servizi; ...di avere una architettura a provider "gratis"; ...di avere i preziosi expression tree senza alcuno sforzo; ... di lavorare in modo strong-typed.
Sento già le ambulanze suonare ma io la vedo così...