czy to zła praktyka, że repozytorium wywołań kontrolera zamiast usługi?
wyjaśnić więcej:
Rozumiem, że w dobrym projekcie kontrolery wywołują serwis i repozytorium użytkowania usługi.
ale czasami w kontrolerze nie mam / potrzebuję żadnej logiki i po prostu muszę pobrać z db i przekazać go do przeglądania.
i mogę to zrobić po prostu wywołując repozytorium - nie trzeba dzwonić do serwisu - czy to zła praktyka?
design-patterns
object-oriented
mvc
repository
mohsenJsh
źródło
źródło
Odpowiedzi:
Nie, pomyśl o tym w ten sposób: repozytorium to usługa (również).
Jeśli podmioty pobierane przez repozytorium obsługują większość logiki biznesowej, nie ma potrzeby korzystania z innych usług. Wystarczy mieć repozytorium.
Nawet jeśli masz jakieś usługi, które musisz przekazać, aby manipulować swoimi bytami. Najpierw pobierz encję z repozytorium, a następnie przekaż ją do wspomnianej usługi. Możliwość podrzucenia HTTP 404 przed próbą jest bardzo wygodna.
Również w przypadku scenariuszy odczytu powszechne jest to, że jednostka musi rzutować ją na model DTO / ViewModel. Posiadanie warstwy usługowej pomiędzy nimi wtedy często powoduje wiele nieprzewidzianych metod.
źródło
Nie jest złą praktyką, że kontroler bezpośrednio wywołuje repozytorium. „Usługa” to po prostu kolejne narzędzie, więc używaj jej tam, gdzie ma to sens.
NikolaiDante skomentował:
Nie uważam, że spójność jest najważniejszym aspektem. Klasa „service” ma za zadanie obudować logikę wyższego poziomu, aby sterownik nie musiał jej implementować. Jeśli dla danej operacji nie jest wymagana „logika wyższego poziomu”, wystarczy przejść bezpośrednio do repozytorium.
Aby promować dobrą separację obaw i testowalność, repozytorium powinno być zależnością wprowadzaną do usługi za pośrednictwem konstruktora:
Jeśli wyszukiwanie rekordów w bazie danych wymaga jakiegoś sparametryzowanego zapytania, klasa usług może być dobrym miejscem do wzięcia pod uwagę modelu widoku i zbudowania zapytania, które jest następnie wykonywane przez repozytorium.
Podobnie, jeśli masz złożony model widoku formularza, klasa usług może zawrzeć logikę tworzenia, aktualizowania i usuwania rekordów poprzez wywoływanie metod w modelach / jednostkach domeny, a następnie utrwalanie ich za pomocą repozytorium.
Idąc w przeciwnym kierunku, jeśli kontroler musi uzyskać rekord według swojego identyfikatora, delegowanie do obiektu usługi jest jak uderzenie palcem w młot kowalski - to znacznie więcej niż potrzebujesz.
Odkryłem, że kontroler jest w najlepszej pozycji do obsługi transakcji lub obiektu Unit Of Work . Kontroler lub obiekt Unit Of Work delegowałby następnie do obsługi obiektów dla złożonych operacji lub przechodził bezpośrednio do repozytorium dla prostych operacji (takich jak znalezienie rekordu według Id).
Myślę, że połączenie usług i bezpośredniej pracy z repozytoriami jest całkowicie do przyjęcia. Możesz dodatkowo zawrzeć transakcję w obiekcie Unit Of Work, jeśli czujesz taką potrzebę.
Podział obowiązków wygląda następująco:
źródło
DbContext
to złe imię w tym przypadku. Zmienię to. Korzystam z NHibernate, a repozytoria (lub kontekst, jeśli jest to przydatne) zarządzają końcem bazy danych, więc zmiana mechanizmów trwałości nie wymaga zmian kodu poza kontekstem.To zależy od twojej architektury. Korzystam z Spring, a transakcjami zawsze zarządzają usługi.
Jeśli wywołujesz repozytoria bezpośrednio w celu wykonania operacji zapisu (lub prostych usług bez logiki, które po prostu delegują się do repozytorium), prawdopodobnie korzystasz z kilku transakcji bazy danych do operacji, którą należy wykonać w jednym. Doprowadzi to do niespójności danych w bazie danych. Zasadniczo operacje na bazach danych powinny działać lub kończyć się niepowodzeniem, ale operacje połowicznej pracy są przyczyną bólów głowy.
Z tego powodu uważam, że wywoływanie repozytoriów bezpośrednio z kontrolerów lub korzystanie z prostych usług delegowania jest złą praktyką. Zaczynasz robić to tylko do czytania, a wkrótce ty lub jeden z twoich kolegów zacznie to robić dla operacji zapisu.
źródło