Związek między repozytorium a jednostką pracy

17

Zamierzam zaimplementować repozytorium i chciałbym użyć wzorca UOW, ponieważ konsument repozytorium może wykonać kilka operacji i chcę je zatwierdzić jednocześnie.

Po przeczytaniu kilku artykułów na ten temat, nadal nie rozumiem, jak powiązać te dwa elementy, w zależności od artykułu, który jest robiony w inny sposób.

Czasami UOW jest czymś wewnętrznym dla repozytorium:

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

A czasem ma charakter zewnętrzny:

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

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

Innym razem jest jednostka organizacyjna, która odwołuje się do repozytorium

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

Jak te dwa elementy są powiązane? UOW śledzi elementy, które należy zmienić, a repozytorium zawiera logikę, aby zachować te zmiany, ale ... kto nazywa kogo? Czy ostatnie mają większy sens?

Kto zarządza połączeniem? Jeśli w repozytorium trzeba wykonać kilka operacji, myślę, że użycie tego samego połączenia, a nawet transakcja, to więcej dźwięku, więc może umieść obiekt połączenia w UOW, a ten w repozytorium również ma sens.

Twoje zdrowie

NullOrEmpty
źródło

Odpowiedzi:

7

Re: „UOW śledzi elementy, które należy zmienić, a repozytorium zawiera logikę, aby zachować te zmiany, ale ... kto dzwoni do kogo?”

Rozumiesz podstawowe obowiązki tych klas. Mówisz, że każdy artykuł, który przeczytałeś, łączy je na różne sposoby. Oznacza to, że decyzja o tym, „kto dzwoni, kto” należy do ciebie.

Spróbuję naszkicować problem w kategoriach „warstw”, kierując się podstawowymi zasadami dobrego projektowania oprogramowania, takimi jak spójność , oddzielenie , możliwość ponownego użycia , testowanie jednostkowe itp.

Cytując Eric Evans Domain Driven Design, (2004) Addison Wesley, str. 69 :

Podstawową zasadą [architektur warstwowych] jest to, że każdy element warstwy zależy tylko od innych elementów w tej samej warstwie lub od elementów warstw „pod nią”.

Moim zdaniem, zarówno UOW, jak i Repo to dwie bardzo różne klasy, które mają jasne, niezależne obowiązki. Na początek nie zmuszałbym żadnego z nich do przywołania drugiego.

Myślę, że potrzebujesz trzeciej klasy klienta (tj. Albo controllerlub service class), która naprawdę wie „kiedy i co uzyskać” z repozytorium i „kiedy”, aby zapisać transakcję. Ten klient znajduje się stosunkowo wysoko w architekturze (dzięki czemu może wiedzieć o większej liczbie klas) i może między nimi zarządzać.

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

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


--------------------------------
JW01
źródło
2

Metody najczęściej podaje się w interfejsie UOW (który zwykle jest konstruowany fabrycznie).

Zazwyczaj wywołujesz metody w interfejsie UOW z klas / klas wzorca poleceń / fasady. Ponieważ UOW po prostu odkłada IO bazy danych na później (aby zapobiec długotrwałym transakcjom lub wielokrotnym wywołaniom bazy danych, które mogą być niepotrzebne), praca z UOW powinna być na tym samym poziomie, na którym normalnie pracowałbyś z bazą danych.

Microsoft ma bardzo dokładny post na temat wzoru UOW:

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

Graeme Wicksted
źródło