Opinia w sprawie ASP.NET MVC Onion-based architecture [zamknięta]

Zamknięte . To pytanie jest oparte na opinii . Obecnie nie przyjmuje odpowiedzi.

Chcesz poprawić to pytanie? Zaktualizuj pytanie, aby mogło być odpowiedź z faktami i cytatami przez edytując ten post .

Zamknięte 3 miesiące temu .

Popraw to pytanie

Jakie jest twoje zdanie na temat poniższego kodu 'generycznego' - najpierw zainspirowany cebulą ASP.NET Architektura MVC: zrzut ekranu Eksploratora rozwiązań

Warstwy, wyjaśnione:

Rdzeń - zawiera model domeny. np. to obiekty biznesowe i ich relacje. Używam Entity Framework do wizualnego projektowania Bytów i relacji między nimi. Pozwala mi wygenerować skrypt do bazy danych. Dostaję automatycznie generowane modele podobne do POCO, do których mogę swobodnie odwoływać się w następnej warstwie (Persistence), ponieważ są proste (tzn. nie są specyficzne dla bazy danych).

Persistence - interfejs repozytorium i implementacje. Zasadniczo CRUD operacje na modelu domeny.

BusinessServices - warstwa biznesowa wokół repozytorium. Cała logika biznesowa powinna być tutaj (np. GetLargestTeam(), itd.). Używa operacji CRUD do komponowania zwracanych obiektów lub pobierania/filtrowania / przechowywania danych. Powinien zawierać wszystkie zasady biznesowe i walidacje.

Web (lub inny interfejs użytkownika) - w tym konkretnym przypadku jest to aplikacja MVC, ale ideą tego projektu jest dostarczenie interfejsu użytkownika, napędzanego tym, co oferują usługi biznesowe. Interfejs użytkownika projekt zużywa warstwę biznesową i nie ma bezpośredniego dostępu do repozytorium. Projekt MVC ma własne modele widoku, które są specyficzne dla każdej sytuacji widoku. Nie próbuję na siłę karmić go modelami domen.

Więc referencje idą tak: UI -> Business Services -> Repository - > Core objects

Co w nim Lubię:

  • mogę projektować moje obiekty, a nie kodować je ręcznie. I am getting Model generowany kodem obiektów.
  • interfejs użytkownika jest napędzany/egzekwowany przez firmę warstwa. Różne aplikacje interfejsu użytkownika mogą być kodowane na podstawie tego samego Model biznesowy.

Mieszane uczucia o:

  • dobrze, mamy implementację repozytorium pluggable, ale jak często naprawdę masz różne implementacje tego samego interfejsu persistence?
  • to samo dotyczy interfejsu użytkownika - mamy techniczną zdolność do wdrażania różnych aplikacji interfejsu użytkownika zgodnie z tymi samymi zasadami biznesowymi, ale dlaczego czy moglibyśmy to zrobić, gdy możemy po prostu renderować różne widoki (mobilne, stacjonarne itp.)?
  • Nie jestem pewien, czy interfejs użytkownika powinien komunikować się tylko z warstwą biznesową za pomocą modeli widoku, czy też powinienem używać modeli domeny do przesyłania danych, tak jak to robię teraz. Do wyświetlania używam modeli widoku, ale do przesyłania danych używam modeli domeny. Źle?

Czego nie lubię:

  • the Core project is now referred in every other project-because I want/have to access modele domen. W klasycznej architekturze cebulowej do rdzenia odwołuje się tylko następna warstwa.
  • DbContext jest zaimplementowany wCore project, ponieważ jest generowany przez ramy Entity, w tym samym miejscu, w którym.edmx jest. Chcę skorzystać z ... EDMX dla projektu modelu wizualnego, ale czuję, że DbContext należy do warstwy Persistence, gdzieś w implementacji repozytorium specyficznej dla bazy danych.

Jako ostatnie pytanie - co to jest dobra architektura, która nie jest nadmiernie zaprojektowana (np. pełnowymiarowa cebula, gdzie mamy zastrzyki, lokalizatory usług itp.), ale jednocześnie zapewnia pewną rozsądną elastyczność, w miejscach, w których realistycznie jej potrzebujesz?

Dzięki

Author: hyankov, 2013-04-12

4 answers

Wow, tu jest wiele do powiedzenia! ;-)

Po pierwsze, porozmawiajmy o ogólnej architekturze.

Widzę, że to nie jest tak naprawdę Architektura cebulowa. Zapomniałeś o zewnętrznej warstwie, warstwie "rozwiązywanie zależności". W architekturze cebulowej do tej warstwy należy podłączenie podstawowych interfejsów do implementacji infrastruktury (gdzie powinien znajdować się projekt Persistence).

Oto krótki opis tego, co powinno się znaleźć w cebuli podanie. To, co wchodzi w warstwę podstawową, to wszystko, co jest unikalne dla firmy: Model domeny, przepływy pracy biznesowej... Warstwa ta definiuje wszystkie techniczne potrzeby implementacji jako interfejsy (np. interfejsy repozytoriów, interfejsy logowania, interfejsy sesji...). Warstwa Podstawowa nie może odwoływać się do żadnych zewnętrznych bibliotek i nie ma kodu specyficznego dla technologii. Druga warstwa to warstwa infrastruktury. Ta warstwa zapewnia implementacje dla interfejsów bazowych innych niż biznesowe. Tu nazywasz swoją DB, Twoje web services ... możesz odwoływać się do dowolnych zewnętrznych bibliotek, których potrzebujesz, aby zapewnić implementacje, wdrożyć tyle pakietów nugget, ile chcesz :-). Trzecia warstwa to Twój UI, dobrze wiesz co tam umieścić; -) a najnowsza warstwa, to Rozdzielczość zależności, o której mówiłem powyżej.

Kierunek zależności między warstwami jest w kierunku środka.

Oto Jak to może wyglądać:

Struktura Aplikacji Onion

Teraz pytanie brzmi: jak dopasować to, co już zakodowałeś w Architektura cebulowa.

Core: contain the Domain model

Tak, to jest właściwe miejsce!

Persistence-interfejs i implementacje repozytoriów

Cóż, będziesz musiał rozdzielić interfejsy z implementacjami. Interfejsy muszą być przeniesione do Core i implementacje muszą być przeniesione do folderu Infrastructure (można to nazwać Persistence projektu).

BusinessServices - warstwa biznesowa wokół repozytorium. Wszystkie logika biznesowa powinna być tutaj

To trzeba przenieść w Core, ale nie powinno się używać implementacji repozytoriów, tylko manipulować interfejsami!

Web (lub jakikolwiek inny UI) - w tym konkretnym przypadku jest to MVC application

Fajne: -)

Musisz dodać projekt "Bootstrapper" , wystarczy spojrzeć tutaj , aby zobaczyć, jak postępować.

O twoich mieszanych uczuciach:

Nie będę dyskutował o potrzebujesz repozytoriów, czy nie, znajdziesz wiele odpowiedzi na stackoverflow.

W moim projekcie ViewModel mam folder o nazwie "Builder". To do moich konstruktorów, aby omówić z moich interfejsów Usług Biznesowych w celu uzyskania danych. Konstruktor otrzyma listy rdzenia.Obiekty domeny i zmapuje je do odpowiedniego ViewModel.

O tym, czego nie lubisz:

W klasycznej architekturze cebulowej do rdzenia odwołuje się tylko następny warstwa.

False ! :- ) Każda warstwa potrzebuje rdzenia, aby mieć dostęp do wszystkich interfejsów zdefiniowanych tam.

DbContext jest zaimplementowany wCore project, ponieważ jest to generowane przez ramy podmiotowe, w tym samym miejscu, w którym.edmx is

Po raz kolejny nie stanowi to problemu, gdy tylko edytowanie szablonu T4 związanego z Twoim EDMX jest naprawdę łatwe. Wystarczy zmienić ścieżkę generowanych plików i można mieć EDMX w warstwa Infrastruktury i POCO są w twoim rdzeniu.Projekt domeny.

Mam nadzieję, że to pomoże!

 26
Author: MaxSC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:34

Wprowadzam swoje usługi do moich kontrolerów. Usługi zwracają DTO, które znajdują się w Core. Model, który masz wygląda dobrze, nie używam wzorca repozytorium, ale wiele osób tak. Trudno mi pracować z EF w tego typu architekturze, dlatego zdecydowałem się na użycie Nhibernate.

Możliwa odpowiedź na twoje ostatnie pytanie.

  1. Rdzeń
  2. domena
  3. DI
  4. Infrastruktura
  5. prezentacja
  6. usługi
 3
Author: CrazyCoderz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-13 13:57:29

Moim zdaniem:

  • " w klasycznej architekturze cebulowej rdzeń odnosi się tylko do następnej warstwy." Nie jest to prawdą, rdzeń powinien być odwołany przez dowolną warstwę... pamiętaj, że kierunek zależności między warstwami jest w kierunku centrum (rdzenia).

Tutaj wpisz opis obrazka

"warstwy powyżej mogą używać dowolnej warstwy pod nimi" Jeffrey Palermo http://jeffreypalermo.com/blog/the-onion-architecture-part-3/

    Jeśli chodzi o Twój EF, to jest w złym miejscu.... Informatyka powinien znajdować się w warstwie infrastruktury, a nie w warstwie rdzenia. I użyj poco Generator do tworzenia encji (klas POCO) w Core/Model. Można też użyć Auto-mapera, aby zmapować Model Podstawowy (obiekty biznesowe) do modelu encji (encje EF)
 2
Author: Jaider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-05 11:55:51

To, co zrobiłeś, wygląda całkiem nieźle i jest w zasadzie jedną z dwóch standardowych architektur, które często widzę.

Mieszane uczucia o:

Dobrze, mamy implementację repozytorium pluggable, ale jak często naprawdę masz różne implementacje tego samego interfejsu persistence?

Pluggable jest często reklamowany jako dobry projekt, ale nigdy nie widziałem, aby zespół zamienił poważną implementację czegoś na coś innego. Tylko modyfikują istniejące rzecz. IMHO "pluggability" jest przydatny tylko dla możliwości makietowania komponentów do automatycznego testowania jednostek.

Nie jestem pewien, czy interfejs użytkownika powinien komunikować się tylko z warstwą biznesową za pomocą modeli widoku, czy też powinienem używać modeli domeny do przesyłania danych, tak jak teraz. Do wyświetlania używam modeli widoku, ale do przesyłania danych używam modeli domeny. Źle?

Myślę, że modele widoku są problemem UI (MVC Web), jeśli dodasz inny typ interfejsu, na przykład może nie wymagać wyświetl Modele lub może potrzebować czegoś innego. Myślę więc, że warstwa biznesowa powinna zwracać encje domeny i pozwalać na mapowanie ich w celu wyświetlania modeli w warstwie interfejsu użytkownika.

Czego nie lubię:

Core project jest teraz odwoływany w każdym innym projekcie - ponieważ Chcę / muszę uzyskać dostęp do Modeli domeny. W klasycznej architekturze cebulowej do rdzenia odwołuje się tylko następna warstwa.

Jak mówili inni, jest to całkiem normalne. Zazwyczaj wszystko kończy się na zależność od domeny.

DbContext jest zaimplementowany wCore project, ponieważ jest generowany przez ramy Entity, w tym samym miejscu, w którym.edmx jest. Chcę skorzystać z ... EDMX dla projektu modelu wizualnego, ale czuję, że DbContext należy do warstwy Persistence, gdzieś w implementacji repozytorium specyficznej dla bazy danych.

Myślę, że jest to konsekwencja struktury podmiotu. Jeśli użyłeś go w trybie "Code First", możesz - i zazwyczaj-mieć kontekst i repozytorium w warstwie Persistance z domeną (reprezentowaną jako klasy POCO) w tym, co nazwałeś rdzeniem.

Jako ostatnie pytanie-co to jest dobra architektura, która nie jest przerobiona (np. pełnowymiarowa cebula, gdzie mamy zastrzyki, lokalizatory usług itp.), ale jednocześnie zapewnia pewną rozsądną elastyczność, w miejscach, w których realnie jej potrzebujesz?

Jako że poruszyłem wyżej nie martwiłbym się o potrzeba wymiany rzeczy z wyjątkiem umożliwienia zautomatyzowanych testów jednostkowych. Chyba że istnieje konkretny wymóg, o którym wiesz, że to bardzo prawdopodobne.

Powodzenia!

 1
Author: Justin Ricketts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55