Архитектура для веб-проекта MVC / использование разных типов моделей - PullRequest
6 голосов
/ 29 февраля 2012

Я строю проект, который в настоящее время имеет 3 сборки:

  • UI
  • Core (Услуги и модели, Утилиты)
  • Репозитории (Linq2SQL)

Зависимости

  • UI -> Core
  • Core -> Хранилища.

Мне бы хотелось, чтобы Сервисы и Модели находились в их собственных сборках и в конечном итоге создавали нечто, построенное вокруг Моделей, т.е.

  • UI -> Модели, Сервисы
  • Услуги -> Модели, хранилища
  • Хранилища -> Модели
  • Модель

Система, которую я создаю, в основном представляет собой CMS для веб-сайта, поэтому у меня будет модель для веб-страницы (PageModel), в которой есть коллекция дочерних веб-страниц. PageModel может вызывать методы в службе (PageService) для заполнения дочерних страниц, но в новом дизайне этого не может быть, потому что сборка Models обязательно ничего не знает о сборке служб.

Я рассмотрел некоторые идеи в Onion Architecture (а именно внедрение зависимостей), чтобы решить эту проблему, но кажется, что может быть доступно более элегантное / очевидное решение.

Нужно ли вводить еще один слой Model? Посмотреть модели? Я думаю, что я называю моделями доменные модели ... Я вполне могу ошибаться! Службы тогда будут доменными службами?

Так что мое решение будет:

  • UI -> Сервисы, ViewModels, Модели
  • ViewModels -> Сервисы, Модели
  • Услуги -> Хранилища, Модели
  • Хранилища -> Модели
  • Модель

В этом примере я предполагаю, что мой PageViewModel расширит PageModel и будет использовать PageService для извлечения дочерних страниц.

Любые предложения приветствуются. Также какие-нибудь указатели на то, как обычно называются эти слои моделей? Я говорю здесь о DTO-моделях, а не о доменных моделях? И доменные модели, а не модели просмотра? Похоже, что то, что я предлагаю использовать для моделей представления, на самом деле не является задачей модели представления ..

Спасибо

EDIT:

Изначально я не упомянул о том, что мои доменные модели не являются базовыми переводами отдельных объектов базы данных, которые вы, как правило, видите в большинстве учебных пособий. Модель домена может содержать поля данных из нескольких связанных таблиц базы данных.

Так стоит ли иметь набор Моделей просто для инкапсуляции данных в Домене - без каких-либо методов / свойств, которые выбирали связанные объекты или сохраняли объект обратно в БД и т. Д.? - Объекты передачи данных.

Посмотрев на пару набросанных диаграмм, это означало бы наличие набора картографов на уровне домена (что кажется неправильным ...) для перевода моделей DTO в Модели домена и обратно. Проект будет строиться вокруг моделей DTO, а не моделей предметной области, но учитывая то, что инкапсулировано DTO, я не вижу в этом проблемы.

Для тех, кто заинтересован, предлагаемая структура зависимостей будет выглядеть так:

  • UI -> Сервисы, доменные модели
  • Услуги -> Хранилища, доменные модели, модели DTO
  • Доменные модели -> Хранилища, DTO-модели
  • Mappers -> доменные модели, модели DTO
  • Хранилища -> Модели DTO
  • Модели DTO (без зависимостей)

Это немного беспорядок! И все только потому, что я хочу, чтобы моя PageModel могла получать свои собственные дочерние PageModels ... Похоже, что внедрение инъекций зависимости не может быть таким плохим планом.

Спасибо ребятам, которые ответили. Вы дали мне множество мыслей.

Ответы [ 3 ]

2 голосов
/ 29 февраля 2012

Я думаю, что для любого приложения "реального мира" довольно типично хранить данные иначе, чем они отображаются на экране.Я думаю, что вы на правильном пути, имея две отдельные "модели".Я обычно заканчиваю тем, что называю их:

  • ViewModels - сопоставление с тем, что отображается на экране, с тем, что хотят представления.
  • DataModels - сопоставление с БД, чтоуровень персистентности (ORM) хочет.

Иногда DataModels называют Entities, особенно когда речь идет о Entity Framework как уровне доступа к данным, или Data Transfer Objects (DTO).

Обычно существует некоторый набор "переводчиков" для сопоставления с представлением и моделям данных, или иногда можно использовать AutoMapper.

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

2 голосов
/ 29 февраля 2012

Я рассмотрел некоторые идеи в Onion Architecture (а именно внедрение зависимостей), чтобы решить эту проблему, но кажется, что может быть доступно более элегантное / очевидное решение.

Как только вы правильно освоите Dependency Injection, это действительно очень элегантное / очевидное решение.

Я бы предложил такую ​​структуру зависимостей:

  • UI
    • Контроллеры -> Сервисы, Модели, ViewModels
    • Просмотров -> ViewModels
    • ViewModels (без зависимостей)
  • Услуги -> Хранилища, Модели
  • Хранилища -> Модели
  • Модель

Это довольно близко к тому, что у вас было раньше, но ваши ViewModels являются частью вашего пользовательского интерфейса и вообще не имеют никаких зависимостей. Это должны быть простые классы, представляющие то, что вы хотите показать пользователю.

Задача Контролера:

  • Вызовите службы для получения моделей,
  • Переведите модели в ViewModels и
  • Вызовите код просмотра

Представления не должны требовать никакой информации, которая не предоставляется ViewModels.

2 голосов
/ 29 февраля 2012

Вы можете сделать это очень хорошо с луковой архитектурой.Например, пользовательский интерфейс, домен, доступ к данным, службы

домен доступа к службам интерфейса пользователя (также содержит модели представления)

Пользовательский интерфейс может получить доступ к любому.Услуги, только доступ к данным и домен.Доступ к данным - только домен.

Мои интерфейсы репозитория находятся в проекте домена, и они реализованы в проекте доступа к данным.Я также сохраняю другие интерфейсы в доменном проекте (IContext, IUnitOfWork и т. Д.), Поэтому у меня есть одно центральное место, и я не распределяю слишком много интерфейсов между проектами.

DTO будут использоваться просто для передачи между слоями, если вы считаете,подходящее.У меня нет причин, по которым вы не можете передать модель предметной области с уровня данных, некоторые предпочитают использовать здесь только DTO.Я сделаю сопоставление на уровне пользовательского интерфейса (бывший контроллер MVC) с ViewModel, поскольку я могу использовать AoP, чтобы сделать это для меня (атрибут [AutoMap ()])

Просто помните, что ваши модели должныне содержит никакой логики постоянства.

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