Relazione tra Repository e Unità di lavoro

16

Ho intenzione di implementare un repository, e vorrei usare il pattern UOW poiché il consumer del repository potrebbe fare diverse operazioni, e voglio impegnarle in una volta.

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

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 questi due elementi sono correlati? UOW tiene traccia degli elementi che devono essere modificati e il repository contiene la logica per mantenere tali modifiche, ma ... chi chiama chi? L'ultimo ha più senso?

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

Saluti

    
posta NullOrEmpty 03.06.2012 - 13:51
fonte

2 risposte

7

Ri: "UOW tiene traccia degli elementi che devono essere modificati e il repository contiene la logica per mantenere tali modifiche, ma ... chi chiama chi?"

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

Cercherò di delineare il problema in termini di "livelli" pur essendo guidato dai principi di base del buon design del software come Cohesion , Disaccoppiamento , Riutilizzabilità , Testabilità unità ecc.

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

The essential principal [of Layered Archituctures] is that any element of a layer depends only on other elements in the same layer or on elements of the layers "beneath" it.

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

Penso che tu abbia bisogno di qualche terza classe client (cioè un controller o service class ) che veramente sa 'quando e cosa ottenere' dal repository e 'quando' per salvare la transazione. Questo client si trova relativamente in alto nell'architettura (quindi sapere su più classi) e può fare un po 'di orchestrazione tra i due.

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

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


--------------------------------
    
risposta data 16.06.2012 - 05:56
fonte
2

I metodi sono comunemente assegnati all'interfaccia UOW (che è normalmente costruita tramite una factory).

In genere, si invocano metodi su un'interfaccia UOW dalla / e classe / i del modello di comando. Dal momento che UOW semplicemente rimuove l'I / O del database fino a un momento successivo (per evitare di avere transazioni di lunga durata o chiamate multiple al database che potrebbero non essere necessarie), lavorare con UOW dovrebbe essere allo stesso livello che normalmente si avrebbe con il database. / p>

Microsoft ha un post molto approfondito sul pattern UOW:

link

    
risposta data 12.06.2012 - 04:36
fonte