2011-01-21 16 views
5

Pracuję nad małym projektem ASP.NET MVC w tej chwili.
Próbuję zaimplementować Nhibernate do utrzymywania na bazie danych MS SQL Server. Spędziwszy długie godziny na studiach DDD i innych projektach znalezionych w Internecie, zdecydowałem się przejść do schematu repozytorium. Teraz mam do czynienia z dylematem.
Czy naprawdę potrzebuję repozytorium podczas korzystania z Nhinbernate?
nie byłoby lepiej mieć warstwę usługi (nie mieć warstwę usługi w tej chwili), który współdziała z Nhinbernate unikając napisać wiele razy coś takiego:ASP.NET MVC, Nhibernate i repozytoria dla małych/średnich projektów

public Domain.Reminder GetById(Guid Code) 
{ 
    return (_session.Get<Domain.Reminder>(Code)); 
} 

public Domain.Reminder LoadById(Guid Code) 
{ 
    return (_session.Load<Domain.Reminder>(Code)); 
} 

public bool Save(Domain.Reminder Reminder) 
{ 
    _session.SaveOrUpdate(Reminder); 
    return (true); 
} 

public bool Delete(Domain.Reminder Reminder) 
{ 
    _session.Delete(Reminder); 
    return (true); 
} 

Znalazłem stary POST Ayende, który jest przeciwko repozytoriom.
Wiem, że wokół tych tematów toczy się wielka debata, a odpowiedź zawsze jest ... zależy, ale wydaje mi się, że przy zbyt wielu warstwach abstrakcji rzeczy stają się bardziej skomplikowane i trudne do naśladowania.
Czy się mylę?

+0

Tylko mała uwaga. Nie ma projektu małego-średniego, może on być na razie mały, ale jutro twój menadżer poprosi cię o inną funkcję, a potem kolejną i drugą, a na końcu będziesz miał ogromny projekt z architekturą małej i średniej wielkości. . Naprawdę nie lubię Big Design Up Front, ale czasami trzeba myśleć trochę dalej. – goenning

+0

Zgadzam się z tobą całkowicie, ale tak naprawdę nie widzę korzyści w korzystaniu z repozytorium, jeśli nie z tego, że mogę nie używać nihbernate w przyszłości. Generuje mnóstwo dodatkowej pracy, której obecnie nie mogę usprawiedliwić. – LeftyX

Odpowiedz

7

Ayende była przeciwna pisaniu repozytorium tak, jak to robiłeś z powodów, dla których zadałeś to pytanie, jest to powtarzalny kod i NH może i tak sobie poradzić. Opowiada się po prostu, aby dzwonić do NH w sposób podobny do repozytorium i przestać się tym martwić.

Prawie się z nim zgadzam. Naprawdę nie ma wiele do zyskania oprócz większej ilości pracy.

+0

Muszę wyznać, że to jest odpowiedź, którą chciałem usłyszeć :-) – LeftyX

0

Znalazłem kilka powodów, dla których powinieneś używać Repozytorium/DAO/Cokolwiek.

  1. Jednostka testowa. Nigdy nie próbowałem naśmiewać się z ISIS, ale powiedziałbym, że powinien być DUŻO bardziej złożony niż kpiny lub krępowanie interfejsu Repository/DAO.
  2. Ponowne użycie kodu. Jeśli napiszesz zapytanie bezpośrednio do swoich usług/kontrolerów, w końcu powielisz je, gdy chcesz ponownie użyć określonego zapytania. Jeśli masz go w repozytorium, po prostu wywołaj jego metodę.
  3. Single Responsibility Principle. Rozprzestrzenianie się zapytań wokół kontrolerów sprawia, że ​​łamiesz tę zasadę.
  4. Zależność NHibernate. Ok, to trudne, ale jeśli chcesz zmienić ORM, repozytoria ułatwiają (spójrz, to łatwiej, nie jest to łatwe :)). A nawet, gdy trzeba zmienić dane użytkownika z bazy danych na Microsoft Active Directory, byłoby łatwiej.

To wszystko, nie pamiętam nic więcej.

+0

Dzięki Oenning. Nie chcę pisać zapytań w kontrolerach, ale w warstwie usługi. Myślę, że jest to dobre miejsce do wprowadzenia logiki biznesowej. Nie byłby w interfejsie użytkownika i byłby wielokrotnego użytku, jeśli chcę podłączyć moją warstwę usługi gdzie indziej. Zależność od Nhibernate. Cóż, tak, mogę się zgodzić, ale nie sądzę, żeby to miało wkrótce nastąpić i nie sądzę, żeby to było coś innego niż zmiana repozytorium. Dzięki i tak. – LeftyX

+0

1. Jeśli próbujesz repo, to używasz wzoru testowego "znanego urządzenia". 2. Nic nie mówi, że nie możesz tworzyć abstrakcji w warstwie usług. To jest całkowicie fałszywe. 3. Wcale nie. Zadzwonisz do db gdzieś. Nie ma znaczenia, czy wywołanie usługi lub wywołania repo, czy też część kontrolera nie ma znaczenia. Wciąż ten sam kod. Kontroler wciąż odpowiada za zapytanie do bazy danych. – jfar

+0

@jfar 1. Co to jest test "znanego urządzenia"? Nigdy nie słyszałem o tym. Zawsze kpię z moich repozytoriów. 2. Jeśli otrzymam to, co powiedziałeś, otrzymasz taki sam projekt jak repozytorium, ale nazwałeś to czymś innym. Masz przykład? Chciałbym zobaczyć kod na ten temat. 3. Kontroler nie ponosi odpowiedzialności za zapytanie do bazy, musi poprosić o to kogoś innego. Otrzymuje żądanie i na jego podstawie deleguje zadania do innych klas i wybiera następny widok. – goenning

4

Zamiast tego użyj ogólnego repozytorium. Jedno repozytorium na klasę może łatwo zostać przesadzone.

Używam jednego repozytorium z metodami Get, Load, Save i różnymi metodami dopasowywania (jeden dla Linq i jeden dla zapytań o moją domenę).

Ostatnia metoda akceptuje implementację ICreateCritiera. Poniżej znajduje się interfejs i jedna jego implementacja.

public interface ICreateCriteria<T> : ICreateCriteria 
{ 
    DetachedCriteria GetCriteria(); 
} 

public class ChallengesAvailableToRound : ICreateCriteria<Challenge> 
{ 
    private readonly Guid _roundId; 

    public ChallengesAvailableToRound(Round round) 
    { 
     _roundId = round.Id; 
    } 

    public DetachedCriteria GetCriteria() 
    { 
     var criteria = DetachedCriteria.For<Challenge>(). 
      CreateAlias("Event", "e"). 
      CreateAlias("e.Rounds", "rounds"). 
      Add(Restrictions.Eq("rounds.Id", _roundId)); 

     return criteria; 
    } 
} 

Pozwala to na łatwe podzielenie się zapytaniami z własnymi klasami i ponowne ich wykorzystanie w całym projekcie.

+0

Podoba mi się twój pomysł Kenny. Spróbuję nad tym popracować. Dzięki – LeftyX

+0

Kenny, myślę, że twoje rozwiązanie jest wystarczająco dobre dla mnie. Dzięki. – LeftyX

Powiązane problemy