Le entità dovrebbero essere accessibili da tutti i livelli di un'applicazione? [chiuso]

4

Sto consultando questo problema per settimane, ma non riesco a trovare una buona discussione. Si riduce a questo: Poiché le entità POCO utilizzate in un dbContext sono di fatto una definizione del database, non dovrebbero essere vincolate al livello di accesso ai dati e non essere visibili al di fuori di esso?

D'altra parte: è conveniente nascondere alcune entità POCO in ViewModels. in modo che le proprietà modificate possano essere trasferite facilmente al livello di accesso ai dati.

Trovo molti esempi di Entità che si fanno strada nell'interfaccia utente, ma anche molti esempi di dove AutoMapper è usato per mappare le proprietà di un ViewModel a un'entità.

Qualcuno può indicarmi alcuni buoni esempi di lavoro o discussioni che potrebbero aiutarmi a fare una scelta ben informata?

    
posta Dabblernl 10.02.2014 - 01:52
fonte

3 risposte

6

Ecco una regola empirica (ma non seguirla ciecamente! Comprendi perché devi usarla!) per la direzione che le tue dipendenze devono seguire

Always depend in the direction of abstraction and stability

Ciò significa che le dipendenze da cui dipendono tutti devono essere le dipendenze che cambiano meno. Tutti dipendono da loro, quindi sono costosi da cambiare. Quindi progettare quelle dipendenze per avere poco o nessun motivo per cambiare!

E un modo per farlo è quello di rendere quelle dipendenze principalmente dall'interfaccia non implementata e una stupida struttura dati che serve solo a trasferire informazioni tra gli oggetti. Quindi, un modulo più supponente, come l'interfaccia utente e il livello di accesso ai dati e varie parti della logica aziendale, implementa tali interfacce con oggetti di grandi dimensioni che svolgono effettivamente il lavoro. Questo è chiamato il principio di inversione delle dipendenze .

Ora, la direzione che la freccia dei livelli deve assumere dipende da chi sta parlando: "L'interfaccia utente deve dipendere dalla logica aziendale che dipende dall'accesso ai dati! No! La logica aziendale deve essere al centro e tutti dipendono da questo! " Molte opinioni e religioni, ma è tutto inutile alla fine. Che importa è l'astrazione. Se le tue dipendenze sono attraverso elementi astratti, allora ce l'hai. Il resto è puro dibattito intellettuale inutile.

Quindi, per rispondere alla tua domanda, ti chiederò un altro "Quali sono le ragioni per cui la tua cosiddetta entità deve cambiare?" Hai la risposta nella tua stessa domanda:

As POCO entities used in a dbContext are in fact a definition of the database

Se la tua entità è una definizione del database, significa che cambierà ogni volta che il database cambia . E se devono conformarsi a un dbContext, ciò significa che hanno un strong accoppiamento con Entity Framework. Se Microsoft decide di cambiare il modo in cui EF lavora, le tue entità dovranno cambiare. Le tue entità non saranno le simpatiche astrazioni di cui hai bisogno per ridurre al minimo l'accoppiamento.

Quindi sì, in tal caso, se vuoi considerarli un modello del database, dovresti nasconderli in un livello di persistenza e assicurarti che nessuno li veda mai che non sanno anche del database .

In sintesi, se vuoi un'applicazione che è ben disaccoppiata e strongmente coesiva, no, non dovrebbero essere dipese da tutti, perché se lo fai, ognuno dipenderà in modo transitorio dalla struttura del database. Quindi ogni volta la modifica del database, l'intera applicazione dovrà cambiare e sarà un problema. Il modo in cui la gente di solito fa fronte è quello di non modificare il database e di introdurre molta rigidità nella memorizzazione dei dati. A un certo punto o l'altro il database sarà necessario cambiare, e a quel punto dovrai pagare un pesante prezzo del debito tecnico.

Quanto sopra era neutrale come posso farcela, il resto sarà più supponente. Sentiti libero di ignorarlo se non si adatta alle tue opinioni.

Le tue entità dovrebbero essere la base della tua domanda e tutti dovrebbero dipendere da loro. Non dovrebbero, mai , essere un'implementazione del database. Il lavoro sull'entità della struttura è di piegare intorno alla tua entità, e se non può farlo, allora non è la struttura che fa per te: buttala via il prima possibile. Non dovrebbe avere alcun potere sulla tua entità. TU decidi come sono strutturate le tue entità. Non comprare la promessa di magia che i conceptor demo ti stanno mostrando. A un certo punto o l'altro dovrai fare qualcosa di inaspettato, tutta la magia scomparirà e dovrai lasciare il tuo bel mondo onirico e scrivere il codice che avevi davvero bisogno dall'inizio.

Cerca di rendere le tue entità un'astrazione del tuo modello di dominio (che è molto meno probabile che cambi), ea quel punto, tutti saranno in grado di dipendere da loro, e il tuo database sarà libero di essere implementato come vuoi tu. All'inizio avrai meno magia e codifichi di più, ma nel tiro lungo vincerai su tutti i conti.

    
risposta data 10.02.2014 - 17:58
fonte
2

Per rispondere correttamente devi considerare 2 aspetti: le entità stesse e la connessione DB.

Naturalmente la connessione DB dovrebbe essere accessibile solo dal livello di accesso ai dati, in modo da avere una superficie ridotta per interagire con il DB.

Le entità che provengono da lì però ... ovviamente se stai recuperando un'entità di sola lettura e passandoti intorno come un semplice vecchio oggetto dati, allora non ci sono problemi, quindi avanti e usali sapendo che sei solo evitando il dolore di creare un intero livello alternativo di oggetti che esistono per passare i dati di entità attraverso i livelli. Voglio dire, potresti creare una nuova classe per inviare i dati al livello di presentazione, e il livello logico potrebbe prendere i dati dall'entità e popolare questa nuova classe ... ma generalmente perché preoccuparti quando puoi semplicemente passare l'entità stessa e salvare te stesso un mucchio di problemi e problemi di prestazioni che copiano i dati.

Tuttavia, diventa più interessante quando è necessario passare i dati indietro. Qui avete o entità persistenti che devono essere appositamente smistate come oggetti speciali (cioè che contengono abbastanza informazioni per ricordare al DB cosa sono e da dove vengono). Ciò inizia a rendere le cose disordinate, e mentre è facile passare semplicemente l'entità, aggiornare i suoi campi e passarli di nuovo al livello del DB, potresti anche aprire l'accesso al tuo DB al client in quel caso! Qui proverei a fare in modo che gli aggiornamenti avvengano tramite metodi speciali sul tuo livello logico che richiamano nel DB per modificarli. Questo impedisce anche il problema in cui si modifica un'entità sul client e non si riesce a ripristinarlo nel DB: si può finire con un'entità modificata che si sta utilizzando, senza rendersi conto che è stata resa orfana da un'altra attività.

Quest'ultima parte è la parte più importante da comprendere: se si utilizzano le entità tramite i layer, sarà necessario passarli su e giù nello stack come un modello client-server complesso, oppure l'integrità dei dati può essere compromessa.

Quindi, tutto sommato, preferirei mantenere le entità nel livello DB.

    
risposta data 10.02.2014 - 17:20
fonte
-1

I am googling this issue now for weeks, but cannot find a good discussion. It boils down to this: As POCO entities used in a dbContext are in fact a definition of the database, shouldn't they be constrained to the Data Access Layer and not be visible outside it?

Questo è un completo fraintendimento dello scopo dei mappatori relazionali di oggetti e della progettazione basata sul dominio. Quello che vuoi è ignoranza della persistenza . Non si dovrebbe modellare una definizione del database ma gli oggetti del dominio del problema e il modo in cui si relazionano e interagiscono tra loro. Non dovresti preoccuparti della persistenza quando progetti il tuo dominio problematico, a meno che tu non stia cercando di combattere i problemi di performance, ad es.

Le entità sono sicuramente una preoccupazione trasversale e sono perfette per usarle in ogni livello dell'applicazione. Tuttavia, se si desidera limitare la modifica di un'entità a un determinato modulo, è possibile nascondere le entità all'interno del modulo e pubblicare solo oggetti DTO che sono di sola lettura per i consumatori esterni al modulo. Ma all'interno del modulo, ogni livello può essere autorizzato a lavorare con l'entità.

On the other hand: it is convenient to hide some POCO entities in the ViewModels. so that changed properties can be passed back easily to the Data Access Layer.

Sì, lo è, e se non lo fai in questo modo, indebolirai il codice inutilmente e finirai con una lasagna antipattern nel peggiore dei casi.

    
risposta data 10.02.2014 - 16:12
fonte

Leggi altre domande sui tag