Perché dovrei volere un layer UnitOfWork se il mio livello di servizio / business logic è abbastanza specifico?

2

Sto entrando nello schema del repository (che adoro), e mentre lo leggevo vedo questo pattern di UnitOfWork in molti articoli. Prima di sapere qualcosa su UnitOfWork stavo semplicemente usando il mio pattern di repository all'interno del mio livello di servizio (business logic). Questo sembra funzionare alla grande quindi mi chiedo perché avere un altro livello (ad esempio UnitOfWork) possa essere utile?

Perché dovrei volere un layer UnitOfWork nel mio livello di servizio / business logic? Se il tuo livello di servizio è sufficientemente specifico e non copre tutto ciò che è sotto il sole, non sembra che sia necessario.

Nota che sto guardando questo da una prospettiva EF. Ho persino letto articoli in cui la gente menziona che DbContext di EF è un UnitOfWork. Allora, perché creare il mio UnitOfWork se EF DbContext lo fa già per me? Perché non creare il mio DbContext nel mio livello di servizio e quindi richiamare i repository di cui ho bisogno e fare tutto bene?

Il repository che ottengo perché semplifica il test dei miei servizi, ma non vedo il vantaggio di un UnitOfWork specialmente se si sta utilizzando un ORM.

    
posta user441521 11.04.2014 - 17:25
fonte

4 risposte

2

Normalmente utilizzo UnitOfWork per astrarre la conoscenza delle transazioni del database (e successivamente funziona bene come un livello di astrazione sul mio orm). L'idea è che i repository sono responsabili della logica di accesso e modifica dei dati, l'unità di lavoro gestisce quando tali azioni vengono eseguite. È un ottimo strumento per rimuovere complessità e chiamate di database ridondanti dalla tua applicazione.

Fondamentalmente, l'unità di lavoro fa parte del tuo repository / livello di accesso ai dati, ti immetti un'unità di fabbrica di lavoro o di un fornitore nei tuoi repository, che la usano per eseguire le loro azioni. Di solito incapsula questa interazione tra l'unità di lavoro e il repository in una classe base "Repository".

C'è un'incredibile quantità di potenza e flessibilità derivante da ciò. I repository possono conoscere meno la tua applicazione e diventare molto più snelli e riutilizzabili. Solitamente attraverso una qualche forma di contenitore IoC, è possibile impostare l'ambito dell'unità di lavoro (PerRequest) ad esempio. Senza modificare alcun codice nei repository, ora puoi ottimizzare dire una pagina web, fare una singola transazione per richiesta web, che in alcune circostanze può portare a un notevole incremento delle prestazioni nella pagina.

Inoltre, avvolgendo la sessione nhibernate in un'unità di implementazione del lavoro, i repository diventano completamente inconsapevoli di quale ORM si sta utilizzando e si concentrano invece sul fornire query e azioni Linq al resto dell'applicazione. Con tutta la gestione delle transazioni prelevata dai tuoi repository, le cose sono molto più pulite e tu hai molta più flessibilità quando si tratta di "Tuning". (Riutilizzare il livello di accesso ai dati in un'applicazione di analisi? Modificare l'unità di ambito di lavoro in modo che sia per file o per 1000 righe e nessun codice nei repository cambia).

Tutto sommato, non realizzo schemi di repository senza un'unità di lavoro. Vanno mano nella mano, ed entrambi sono più facili da fare con l'altro presente.

    
risposta data 11.04.2014 - 17:41
fonte
0

Il tuo livello di servizio potrebbe sembrare semplice ora, ma se stai creando questa applicazione per un cliente, alla fine modellerai il livello di servizio, non tu.

Che cosa succede se il client richiede che possano modificare più elementi contemporaneamente, modificando un numero qualsiasi di proprietà di elementi, alcuni dei quali fanno parte di tabelle di database denormalizzate? Cosa succede quando EF genera un'eccezione di concorrenza durante uno di questi commit?

Le cose possono diventare davvero complicate velocemente. Solo perché esiste un pattern non significa che devi trovare un posto per applicarlo nella tua applicazione. Una risposta alla tua domanda è che potresti volere un livello UoW aggiuntivo quando devi implementare la tua logica di tracciamento delle modifiche e di gestione della concorrenza oltre a ciò che EF fornisce come parte di DbContext.

    
risposta data 11.04.2014 - 18:26
fonte
0

Da: link

Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

Il problema è qui:

So why make my own UnitOfWork if EF's DbContext already does this for me?

Se si utilizza un modello di repository classico, il livello di servizio non saprebbe che esiste un DbContext o un db, il livello di servizio conosce solo un repository e che chiamando il repository ottiene i dati da parti sconosciute e lo restituisce.

se il livello di servizio non è a conoscenza del meccanismo di archiviazione, come eseguirà una transazione? come eseguirà interazioni simili a transazioni tra diversi provider (diversi database, servizi Web, ecc.)? Il pattern UnitOfWork è più generale di una transazione di database e aiuta a coordinare i repository in modo transazionale, spanning database, potenzialmente anche spanning richieste client.

    
risposta data 11.04.2014 - 19:14
fonte
0

Se sei sicuro al 100% che non cambierai il tuo ORM in futuro, allora non c'è bisogno di usare UOW, EF lo fa per te, ma se c'è la necessità di cambiare il tuo ORM in futuro, (per esempio se hai bisogno di creare tabelle dinamiche, o un ORM che sia più performante di EF) se hai un livello UOW che astrae il tuo DbContext, troverai facile modificare l'ORM.

    
risposta data 12.04.2014 - 18:29
fonte

Leggi altre domande sui tag