Rapporto tra deposito e unità di lavoro


17

Intendo implementare un repository e vorrei utilizzare il modello UOW poiché il consumatore del repository potrebbe eseguire diverse operazioni e desidero impegnarle contemporaneamente.

Dopo aver letto diversi articoli sull'argomento, non riesco ancora a mettere in relazione questi due elementi, a seconda dell'articolo che viene fatto in modo diverso.

A volte l'UOW è qualcosa di interno al repository:

public class Repository
{
    UnitOfWork _uow;

    public Repository()
    {
       _uow = IoC.Get<UnitOfWork>();
    }

    public void Save(Entity e)
    {
        _uow.Track(e);
    }

    public void SubmittChanges()
    {
        SaveInStorage(_uow.GetChanges());
    }
}

E a volte è esterno:

public class Repository
{
    public void Save(Entity e, UnitOfWork uow)
    {
        uow.Track(e);
    }

    public void SubmittChanges(UnitOfWork uow)
    {
        SaveInStorage(uow.GetChanges());
    }
}

Altre volte, è l'UOW che fa riferimento al repository

public class UnitOfWork
{
    Repository _repository;

    public UnitOfWork(Repository repository)
    {
       _repository = repository;
    }

    public void Save(Entity e)
    {
        this.Track(e);
    }

    public void SubmittChanges()
    {
       _repository.Save(this.GetChanges());
    }
}

In che modo sono collegati questi due elementi? UOW tiene traccia degli elementi che devono essere modificati e il repository contiene la logica per persistere a quei cambiamenti, ma ... chi chiama chi? L'ultimo ha più senso?

Inoltre, chi gestisce la connessione? Se nel repository devono essere eseguite diverse operazioni, penso che usare la stessa connessione e persino la transazione sia più valido, quindi magari mettere l'oggetto di connessione all'interno dell'UOW e anche questo all'interno del repository ha senso.

Saluti


Risposte:


7

Ri: "UOW tiene traccia degli elementi che devono essere cambiati e il repository contiene la logica per persistere a quei cambiamenti, ma ... chi chiama chi?"

Comprendi le responsabilità di base di queste classi. Dici che ciascuno degli articoli che hai letto li collega in modi diversi. Ciò implica che la decisione su "chi chiama chi" dipende da te.

Cercherei di delineare il problema in termini di 'strati' pur essendo guidato da principi di base della buona progettazione software come coesione , disaccoppiamento , riutilizzabilità , unita Testability etc.

Per citare Eric Evans Domain Driven Design, (2004) Addison Wesley, pag 69 :

Il principio essenziale [di Layered Archituctures] è che qualsiasi elemento di uno strato dipende solo da altri elementi nello stesso strato o da elementi degli strati "sotto" di esso.

A mio avviso, sia UOW che Repo sono due classi molto diverse che hanno responsabilità chiare, indipendenti. Per cominciare, non farei invocare l'altro.

Penso che sia necessaria una terza classe di client (ovvero una controllero o service class) che sappia davvero "quando e cosa ottenere" dal repository e "quando" per salvare la transazione. Questo client si trova relativamente in alto nell'architettura (quindi può conoscere più classi) e può fare un po 'di orchestrazione tra i due.

--------------------------------

         [Client]
           /   \
----------/---- \---------------
         /       \
        V         V
[Unit Of Work]  [Repo]


--------------------------------

2

I metodi sono più comunemente forniti all'interfaccia UOW (che è normalmente costruita tramite una fabbrica).

In genere si chiamano metodi su un'interfaccia UOW da classi di comando / es. / Facciata. Dato che UOW semplicemente ignora l'I / O del database in un secondo momento (per evitare di avere transazioni di lunga durata o più chiamate al database che potrebbero non essere necessarie), lavorare con UOW dovrebbe essere allo stesso livello in cui normalmente lavorereste con il vostro database.

Microsoft ha un post molto approfondito sul modello UOW:

http://msdn.microsoft.com/en-us/magazine/dd882510.aspx

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.