2013-01-09 31 views
7

Jaka jest najlepsza praktyka w odwzorowywaniu elementów bazy danych na modele i wykonywanie logiki biznesowej? Widziałem znacznie różne implementacje obu. Zauważyłem wiele implementacji, w których repozytorium (w warstwie danych) samo jest odpowiedzialne za mapowanie jednostek bazy danych do modeli domen. Na przykład, repozytorium że byłoby to zrobić:Odwzorowywanie obiektów na modele i realizowanie logiki biznesowej w środowisku ASP.NET MVC

public IQueryable<Person> GetPersons() 
{ 
     return DbSet.Select(s => new Person 
        { 
         Id = s.Id, 
         FirstName= s.FirstName, 
         Surname= s.Surname, 
         Location = s.Location, 
        }); 
} 

ale o poszukiwanej kompleksowo wokół SO na N Tier projektu, Zauważyłem, że podczas gdy nie ma panaceum, w większości przypadków jest to wskazane, aby wykonać mapowanie wewnątrz kontroler w projekcie MVC ręcznie lub za pomocą programu Mapper. Zostało również powtórzone, że warstwa Serwisu nigdy nie powinna wykonywać mapowania i że odpowiedzialność powinna spoczywać na logice biznesowej. Kilka pytań tutaj:

  1. Która metoda jest wskazana w odniesieniu do tego, gdzie mapować jednostki do modeli i odwrotnie? Czy repozytorium powinno to zrobić, czy też powinno się wykonać mapowanie w kontrolerze?
  2. Załóżmy, że chcę wykonać jakąś logikę biznesową na elementach, które pobrałem z bazy danych, na przykład zwrócić pełną nazwę Person lub zwiększyć wiek wszystkich Person s przez 10 lat, gdzie powinna to być operacja wejść na afisz. Na samym modelu? Na przykład czy mam na modelu właściwość FullName, która oblicza imię i nazwisko oraz wiek? Czy mogę zdefiniować jakąś usługę wewnątrz mojej warstwy usługi, aby wykonać logikę biznesową?

EDIT

Wow tak wielu bliskich głosów. Przepraszam, nie szukałem wystarczająco dokładnie. W 'gdzie do wykonywania logiki biznesowej' Mam problem podniesiony tutaj można już znaleźć na SO i gdzie indziej (choć nieco tajemniczo przekazywane w czasie):

Validating with a Service Layer by Stephen Walther

Skinny Controllers

Another great, but more generic answer here on SO

Where Should I put My Controller Business Logic in MVC

Does a Service Map Entities to a View Model

Jednak wciąż nie znalazłem standardowego rozwiązania mojego pytania dotyczącego mapowania i myślę, że mogłem być może bardziej wymownie wypowiedzieć moje pytanie. Ogólny konsens wydaje się taki, że logika biznesowa wchodzi w warstwę usługi, a mapowanie modeli domenowych na modele widokowe powinno odbywać się w warstwie kontrolera/prezentacji. Ponieważ wskazane jest, aby nie umieszczać obiektów DB w żadnych warstwach innych niż warstwa danych, zaleca się mapowanie swoich jednostek do modeli domen w warstwie danych ręcznie lub za pomocą narzędzia odwzorowującego, takiego jak Auto Mapper (to jest to, co zebrałem od czytanie wielu artykułów). Moje zamieszanie pojawiło się w związku z pytaniem, gdzie należy mapować jednostki do modeli domen i mapować modele domen, aby wyświetlić modele. Jednak, jak już wcześniej wspomniałem, mogłem wyrazić moje pytanie jaśniej. Powodem mojego nieporozumienia było to, że przeczytałem, że jednostki odwzorowujące do modeli domen powinny się zdarzyć w kontrolerze, należy to raczej zmienić, aby powiedzieć: "Odwzorowywanie obiektów na modele domen powinno się odbywać później w danych, a mapowanie modeli domenowych, aby wyświetlać modele powinien mieć miejsce w kontrolerze

Odpowiedz

4
  1. Która metoda jest wskazane w odniesieniu do miejsca, gdzie do mapowania podmioty modeli i vice versa? Czy repozytorium powinno to zrobić, czy też powinno być wykonane mapowanie w kontrolerze?

Zdecydowanie wolę widzieć mapowanie w repozytorium, a nie kontrolera. Kontroler musi działać wyłącznie jako koordynator, o czym Suhas wspomina w swojej odpowiedzi. Jako alternatywa, może można wykorzystać klasę mapowania w repozytorium, która przechodzi na podmiot i zwracają odwzorowaną modelu - tak jakby Auto Mapper

  1. Przypuśćmy, że chcesz wykonać jakiś interes logika na obiektach, które I pobrała z bazy danych, na przykład zwróć pełną nazwę osób, lub zwiększ wiek wszystkich osób o 10 lat, , gdzie należy wykonać tę operację. Na samym modelu? Dla przykładu, czy miałbym na przykład właściwość FullName w modelu, który byłby obliczyć imię i nazwisko oraz wiek? Czy mogę zdefiniować niektóre usługi wewnątrz mojej warstwy usługi do wykonania logiki biznesowej?

Jeśli jest to możliwe, należy wykonać logikę biznesową usługi. Po co nakładać obciążenie na aplikację, aby zrobić to, co powinna zrobić warstwa serwisowa? Uważam, że jest to domena usługi, a nie aplikacja. Ponadto, nie sądzę, aby zwracanie cech konkatenacji lub wyprowadzonych z modelu było złym rozwiązaniem.

Podsumowanie:

  • Kontroler obsługuje żądania od poglądów i przekazuje je do repozytorium
  • Repozytorium jest przewód do magazynów danych
  • Serwis obsługuje żądania z repozytorium, przetwarza logikę biznesową, i powraca odwzorowaną modele
1

Zazwyczaj tworzę małą warstwę usług w ramach projektu MVC, aby obsłużyć dodatkową pracę, którą musi wykonać warstwa MVC.Tak więc w twoim przykładzie możesz mieć PersonService lub , który wywołuje twoją warstwę biznesową, aby uzyskać wszystkie osoby, a następnie podnieść wiek wszystkich osób o 10 lat (przy założeniu, że nie jest to logika biznesowa, ale tylko coś, czego potrzebuje UI), łącz pierwsze imię i nazwisko, aby zbudować pełną nazwę itp. Kontroler następnie po prostu woła do tej usługi i nigdy nie wie, co dzieje się za kulisami. W ten sposób twój kontroler robi to, co powinien idealnie robić - koordynuje widok i model.

1

Zależy od ... Tak jak powiedziałeś nie jest srebrną kulą. Można wymienić tylko plusy i minusy każdego podejścia, ale to ty znasz swoje wymagania lepiej niż ktokolwiek inny tutaj. Jeśli masz czas, proponuję przeczytać tę książkę Patterns of Enterprise Application Architecture. Zapewni to dobre zrozumienie różnych schematów logiki biznesowej i źródeł danych, kiedy i jak z nich korzystać. Co powinno przejść do warstwy biznesowej i co powinno przejść do DAL. Książka zajmuje się także kwestią mapowania z DAL na encje Domain. Możesz nawet zmienić zdanie i wybrać zupełnie inne podejście na dłuższą metę.

Należy również rozważyć użycie ORM, które zapewnia mechanizm Code First, taki jak EF Code First lub NHibernate. W takim przypadku cała logika mapowania będzie dla ciebie przejrzysta.

1

Warstwa dostępu do danych (repozytorium) powinna obsługiwać tylko wstawianie/aktualizację/pobieranie jednostek danych. Twoja warstwa usług obsługuje logikę biznesową i odpowiada za komunikację między warstwą prezentacji (kontroler, modele widoku) i warstwą danych. Oznacza to, że konwersja z jednostek danych do domeny powinna nastąpić na tej warstwie. Twoja warstwa prezentacji (kontroler) powinna obsługiwać konwersję między modelami widoku i modelami domen. -Jeśli chcesz lepiej zrozumieć, powinieneś wziąć porady i wzięte przez Maksyma Wzorce Architektury Aplikacji Przedsiębiorstw, ponieważ uważam (i wiele innych) za Fowlera jako organ do tworzenia aplikacji internetowych. Kolejną dobrą książką jest ASP.NET Design Patterns, który jest oparty na książce Fowlera, ale koncentruje się tylko na ASP.NET Framework.