Подтвердить что ты не робот

Мнение о архитектуре ASP.NET MVC Onion

Каково ваше мнение о следующей "общей" кодовой первой архитектуре ASP.NET MVC, разработанной Onion: screenshot of the solution explorer

Слои, объясненные:

Core - содержит модель домена. например что бизнес-объекты и их отношения. Я использую Entity Framework для визуального проектирования объектов и отношений между ними. Это позволяет мне генерировать script для базы данных. Я получаю автоматически созданные POCO-подобные модели, на которые я могу свободно ссылаться на следующем уровне (Persistence), поскольку они просты (т.е. Они не зависят от базы данных).

Персистирование - интерфейс и реализации репозитория. В основном операции CRUD в модели домена.

BusinessServices - бизнес-уровень вокруг репозитория. Вся бизнес-логика должна быть здесь (например, GetLargestTeam() и т.д.). Использует операции CRUD для создания возвращаемых объектов или получения/фильтрации/хранения данных. Должны содержать все бизнес-правила и проверки.

Веб (или любой другой пользовательский интерфейс). В этом конкретном случае это приложение MVC, но идея этого проекта заключается в предоставлении пользовательского интерфейса, основанного на том, что предлагают бизнес-услуги. Проект пользовательского интерфейса потребляет бизнес-уровень и не имеет прямого доступа к репозиторию. Проект MVC имеет свои собственные модели просмотра, которые являются специфическими для каждой ситуации просмотра. Я не пытаюсь принудительно подавать его в доменные модели.

Итак, ссылки выглядят так: UI → Бизнес-услуги → Репозиторий → Основные объекты

Что мне нравится:

  • Я могу конструировать свои объекты, а не закодировать их вручную. я осознаю созданных кодом объектов Model.
  • Пользовательский интерфейс управляется/выполняется слой. Различные приложения пользовательского интерфейса могут быть закодированы против того же Бизнес-модель.

Смешанные чувства о:

  • Хорошо, у нас есть реалистичная реализация репозитория, но как часто у вас действительно разные реализации одного и того же интерфейса настойчивости?
  • То же самое касается интерфейса - у нас есть технические возможности для реализации различных приложений пользовательского интерфейса по тем же бизнес-правилам, но зачем нам это делать, когда мы можем просто визуализировать разные виды (мобильные, настольные и т.д.)?
  • Я не уверен, что пользовательский интерфейс должен только взаимодействовать с бизнес-слоем через модели просмотра, или я должен использовать модели доменов для передачи данных, как и сейчас. Для отображения я использую модели просмотра, но для передачи данных я использую модели домена. Неправильно?

Что мне не нравится:

  • Проект Core теперь ссылается во всех других проектах - потому что я хочу/должен получить доступ к моделям Домен. В классической архитектуре лука на ядре ссылается только следующий слой.
  • DbContext реализован в проекте .Core, поскольку он генерируется Entity Framework в том же месте, где находится .edmx. Я действительно хочу использовать .EDMX для визуального моделирования модели, но я чувствую, что DbContext принадлежит к слою Persistence, где-то внутри реализации репозитория конкретной базы данных.

В качестве окончательного вопроса - что такое хорошая архитектура, которая не слишком переработана (например, полноразмерный лук, где у нас есть инъекции, локаторы сервисов и т.д.), но в то же время обеспечивает некоторую разумную гибкость, в местах где вам это реально нужно?

Спасибо

4b9b3361

Ответ 1

Ничего себе, здесь многое сказать!; -)

Прежде всего, давайте поговорим об общей архитектуре.

То, что я вижу здесь, это то, что на самом деле это не лунная архитектура. Вы забыли внешний слой, слой "Разрешение зависимостей". В архитектуре Onion, вплоть до этого уровня, для подключения основных интерфейсов к реализации инфраструктуры (где должен находиться ваш проект Persistence).

Вот краткое описание того, что вы должны найти в приложении "Лук". Что касается уровня Core, все это уникально для бизнеса: модель домена, бизнес-процессы... Этот уровень определяет все потребности в технической реализации в качестве интерфейсов (например: интерфейсы репозиториев, интерфейсы ведения журнала, интерфейсы сеансов...). Уровень ядра не может ссылаться на любые внешние библиотеки и не имеет специального кода для конкретной технологии. Второй уровень - это уровень инфраструктуры. Этот уровень обеспечивает реализацию для не-бизнес-интерфейсов Core. Здесь вы вызываете свою БД, свои веб-службы... Вы можете ссылаться на любые внешние библиотеки, которые вам нужны для обеспечения реализаций, развертывать столько пакетов самородок, сколько хотите:-). Третий уровень - это ваш пользовательский интерфейс, ну, вы знаете, что добавить туда;-) И последний уровень, его разрешение зависимостей, о котором я говорил выше.

Направление зависимости между слоями относится к центру.

Вот как это могло бы выглядеть:

Onion App Structure

Теперь возникает вопрос: как подогнать то, что вы уже закодировали в архитектуре лука.

Ядро: содержит модель домена

Да, это подходящее место!

Стойкость - интерфейс и реализации репозитория

Ну, вам нужно разделить интерфейсы с реализациями. Интерфейсы необходимо перенести в Core, а реализации необходимо перенести в папку Infrastructure (вы можете назвать этот проект Persistence).

BusinessServices - бизнес-уровень вокруг репозитория. Все бизнес-логика должна быть здесь

Это нужно перенести в Core, но здесь вы не должны использовать реализации репозиториев, просто манипулируйте интерфейсами!

Web (или любой другой пользовательский интерфейс). В этом конкретном случае это MVC Приложение

cool: -)

Вам нужно добавить проект "Bootstrapper", просто посмотрите здесь, чтобы узнать, как продолжить.

О ваших смешанных чувствах:

Я не буду обсуждать необходимость наличия репозиториев или нет, вы найдете много ответов на stackoverflow.

В моем проекте ViewModel у меня есть папка под названием "Builder". Его до моих Строителей обсуждать с моими интерфейсами бизнес-сервисов для получения данных. Строитель получит списки объектов Core.Domain и отобразит их в правую ViewModel.

О том, что вам не нравится:

В классической архитектуре лука на ядре ссылаются только следующие слой.

Ложь!:-) Каждому слою требуется, чтобы Core имел доступ ко всем интерфейсам, определенным там.

DbContext реализован в проекте .Core, поскольку он созданный платформой Entity Framework, в том же месте, где .edmx это

Еще раз, это не проблема, как только ее очень легко редактировать шаблон T4, связанный с вашим EDMX. Вам просто нужно изменить путь к сгенерированным файлам, и вы можете иметь EDMX на уровне инфраструктуры и POCOs в вашем проекте Core.Domain.

Надеюсь, это поможет!

Ответ 2

Я ввожу свои службы в свои контроллеры. Службы возвращают DTO, которые находятся в Core. Модель у вас хорошо выглядит, я не использую шаблон репозитория, но многие люди делают это. Мне сложно работать с EF в этом типе архитектуры, поэтому я решил использовать Nhibernate.

Возможный ответ на ваш последний вопрос.

  • CORE
  • DOMAIN
  • DI
  • ИНФРАСТРУКТУРА
  • ПРЕЗЕНТАЦИЯ
  • УСЛУГИ

Ответ 3

По-моему:

  • "В классической архитектуре лука на ядре ссылается только следующий слой". Это не так, Core должен быть ссылкой любым слоем... помните, что Направление зависимости между слоями относится к центру (Core).

enter image description here

"слои выше могут использовать любой слой под ними". Джеффри Палермо http://jeffreypalermo.com/blog/the-onion-architecture-part-3/

  • О вашем EF, он находится в неправильном месте.... он должен быть в слое Infrastructure не на уровне Core. И используйте POCO Generator для создания сущностей (классы POCO) в Core/Model. Или используйте Auto-mapper, чтобы вы могли сопоставить Core Model (Бизнес-объекты) с Entity Model (EF Entities)

В другой руке я создал простое приложение с использованием Onion Architecture, чтобы показать зависимости между уровнями и способы их реализации. http://www.jaider.net/posts/935-onion-architecture-in-action-get-started/

enter image description here

Ответ 4

То, что вы сделали, выглядит довольно хорошо и в основном является одной из двух стандартных архитектур, которые я вижу много.

Смешанные чувства о:

Хорошо, у нас есть реалистичная реализация репозитория, но как часто у вас действительно разные реализации одного и того же интерфейса персистентности?

Pluggable часто рекламируется как хороший дизайн, но я ни разу не видел, как команда меняет основную реализацию чего-то для чего-то другого. Они просто изменяют существующее. IMHO "подключаемость" полезна только для того, чтобы быть в состоянии издеваться над компонентами для автоматизированных модульных испытаний.

Я не уверен, что пользовательский интерфейс должен только взаимодействовать с бизнес-слоем через модели просмотра или использовать модели домена для передачи данных, как и сейчас. Для отображения я использую модели просмотра, но для передачи данных я использую модели домена. Неправильно?

Я считаю, что модели просмотра представляют собой проблему с интерфейсом UI (MVC Web), если вы добавили другой тип пользовательского интерфейса, например, он может не потребовать просмотра моделей или может потребоваться что-то другое. Поэтому я думаю, что бизнес-уровень должен возвращать объекты домена и разрешать их сопоставление для просмотра моделей в слое пользовательского интерфейса.

Что мне не нравится:

Проект Core теперь ссылается на каждый другой проект - потому что я хочу/должен получить доступ к моделям Домен. В классической архитектуре лука на ядре ссылается только следующий слой.

Как говорили другие, это вполне нормально. Обычно все заканчивается тем, что имеет зависимость от Домена.

DbContext реализуется в проекте .Core, потому что он генерируется платформой Entity Framework в том же месте, где находится .edmx. Я действительно хочу использовать .EDMX для визуального моделирования модели, но я чувствую, что DbContext относится к уровню Persistence, где-то в реализации репозитория конкретной базы данных.

Я думаю, что это является следствием Entity Framework. Если вы использовали его в режиме "Первый код", вы фактически можете - и обычно - иметь контекст и репозиторий на уровне Persistance с Доменом (представленным как классы POCO) в том, что вы назвали Core.

В качестве окончательного вопроса - что такое хорошая архитектура, которая не слишком переработана (например, полноразмерный лук, где у нас есть инъекции, локаторы сервисов и т.д.), но в то же время обеспечивает некоторую разумную гибкость, в местах где вам это реально нужно?

Как я коснулся выше, я не стал бы беспокоиться о необходимости замены вещей, кроме как для автоматических модульных тестов. Если не существует конкретного требования, о котором вы знаете, это очень вероятно.

Удачи!