Relación entre repositorio y unidad de trabajo


17

Voy a implementar un repositorio, y me gustaría usar el patrón UOW ya que el consumidor del repositorio podría hacer varias operaciones, y quiero comprometerlas a la vez.

Después de leer varios artículos sobre el tema, todavía no entiendo cómo relacionar estos dos elementos, dependiendo del artículo que se está haciendo de una manera u otra.

A veces, el UOW es algo interno del repositorio:

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());
    }
}

Y a veces es externo:

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

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

Otras veces, es el UOW quien hace referencia al Repositorio

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());
    }
}

¿Cómo se relacionan estos dos elementos? UOW rastrea los elementos que necesitan ser cambiados, y el repositorio contiene la lógica para persistir esos cambios, pero ... ¿quién llama a quién? ¿El último tiene más sentido?

Además, ¿quién gestiona la conexión? Si se deben realizar varias operaciones en el repositorio, creo que usar la misma conexión e incluso la transacción es más sólido, por lo que quizás poner el objeto de conexión dentro del UOW y este dentro del repositorio también tenga sentido.

Salud


Respuestas:


7

Re: "UOW rastrea los elementos que necesitan ser cambiados, y el repositorio contiene la lógica para persistir esos cambios, pero ... ¿quién llama a quién?"

Entiendes las responsabilidades básicas de estas clases. Dices que cada uno de los artículos que has leído los conecta de diferentes maneras. Esto implica que la decisión sobre "quién llama a quién" depende de usted.

Intentaría esbozar el problema en términos de 'capas' mientras me guiaba por principios básicos de un buen diseño de software como Cohesión , Desacoplamiento , Reutilización , Unidad-Testabilidad, etc.

Citando a Eric Evans Domain Driven Design, (2004) Addison Wesley, página 69 :

El principio esencial [de las capas de capas] es que cualquier elemento de una capa depende solo de otros elementos en la misma capa o de elementos de las capas "debajo" de ella.

En mi opinión, tanto el UOW como el Repo son dos clases muy diferentes que tienen responsabilidades claras e independientes. Para empezar, no haría que ninguno invoque al otro.

Creo que necesitas un tercero clase de cliente (es decir, una controllero service class) que realmente sepa "cuándo y qué obtener" del repositorio y "cuándo" para guardar la transacción. Este cliente ocupa un lugar relativamente alto en la arquitectura (por lo que puede saber acerca de más clases) y puede hacer cierta orquestación entre los dos.

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

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


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

2

Los métodos se dan más comúnmente a la interfaz UOW (que normalmente se construye a través de una fábrica).

Por lo general, llama a métodos en una interfaz UOW desde clase (s) de patrón de comando / fachada. Como UOW simplemente difiere la base de datos IO hasta más tarde (para evitar que tenga transacciones de larga duración o múltiples llamadas a la base de datos que pueden ser innecesarias), trabajar con UOW debería estar al mismo nivel que normalmente trabajaría con su base de datos.

Microsoft tiene una publicación muy completa sobre el patrón UOW:

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.