Учитывая следующие архитектурные изменения и вам нужен совет (объекты домена, DTO, агрегаты)

Около года назад я установил решение, состоящее из уровня представления ASP.Net MVC 3 (сейчас), уровня приложения, уровня домена и уровня инфраструктуры (пересекающихся материалов и данных). Я решил сохранить модель предметной области в отдельном проекте от логики предметной области и использовать расслабленный подход к уровню представления, передав сущности предметной области вместо DTO, поскольку сейчас у нас действительно только 1 интерфейс.

Вскоре мы собираемся обслуживать распределенный уровень в дополнение к нашему основному веб-сайту, и я буду использовать там DTO, но я также рассматриваю возможность использования DTO на основном веб-сайте. Мне также интересно, стоит ли мне потрудиться, чтобы разбить код фреймворка на уровне домена (IRepository, IUnitOfWork, супертипы объектов Entity / Value и т. Д.). Итак, позвольте мне перечислить вопросы, по которым мне нужна обратная связь:

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

2) Прямо сейчас у меня есть проект предметной области, который содержит сервисы, спецификации и логику предметной области и управляется прикладным уровнем и отдельным проектом для модели предметной области (используется уровнем представления и уровнем приложения). У меня также есть интерфейсы фреймворка для общего репозитория и шаблона единицы работы. Должен ли я разбить фреймворк на отдельный проект, а остальное объединить в один?

3) Я хочу реорганизовать свой уровень домена в агрегаты, прямо сейчас вся модель домена организована по модулям, в основном все типы для каждого модуля находятся в одном пространстве имен. Было бы лучше организовать сущности, объекты значений, услуги и прочее по агрегатам?

4) Следует ли мне использовать шаблон раздельного интерфейса для служб инфраструктуры, которые в основном являются вспомогательными библиотеками .NET Framework? Например, объекты конфигурации или средства проверки? Какая в этом польза?

5) Наконец, я видел не так много примеров, в которых использовались интерфейсы для сущностей предметной области. Почти каждый объект, который у меня есть, я предпочитаю передавать по интерфейсам по причинам зависимости, и это значительно упрощает тестирование. Допустимо ли использовать интерфейсы вместо бетона? Я должен упомянуть, что мы используем EF 4.3.1 (скоро для обновления до последней версии), и я, кажется, помню, что у EF была проблема с использованием интерфейсов или что-то в этом роде. Должен ли я показывать интерфейсы вместо сущностей домена?

Заранее большое спасибо.

Структура проекта:

Presentation.Web
     |       |
     |    Application
     |     |      |
Domain.Model - Domain

(Infrastructure.Data, Infrastructure.Core, Infrastructure.Security)

Объяснение: Presentation.Web (веб-проект MVC3)

Приложение - уровень обслуживания, который управляет уровнем домена и отвечает на запросы уровня представления (получите это обновление). Это организовано по модулям, например, если бы у меня был клиентский модуль, у меня был бы Application.Customer, и в нем были бы все службы приложения.

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

Domain.Model - содержит сущности и перечисления домена. Организовано по модулю. Например, если у меня может быть модуль клиента, у которого есть сущность клиента, сущность customerorder и т. Д. Это отделено от проекта домена, так что объекты могут использоваться на уровне приложения и презентации.

Infrastructure.Security - Инфраструктура безопасности для аутентификации и авторизации.

Infrastructure.Core - сквозной материал, используемый на нескольких уровнях (валидаторы, ведение журнала, конфигурация, расширения, IoC, электронная почта и т. Д.). Большинство проектов зависят от интерфейсов в этом проекте (кроме domain.model) для служб инфраструктуры.

Infrastructure.Data - реализации репозитория через LINQ и EF 4.3.1, слой сопоставления, реализация единицы работы. Интерфейсы находятся в проекте домена (разделенный шаблон интерфейсов)


person user546077    schedule 09.10.2012    source источник
comment
(1) В чем разница между вашей моделью предметной области и логикой предметной области? Что есть в каждом проекте и как вы понимаете разделение. Какую пользу вы получаете от их разлуки? (2) Что вы называете модулем? Вы имеете в виду модуль VB? (3) В чем разница между вашими DTO, вашими интерфейсами и вашими объектами модели предметной области? Можете ли вы опубликовать образец и отметить, из какого проекта каждый компонент? Так было бы легче понять ваш дизайн. Мы можем вам помочь, но мы слишком много гадаем.   -  person smartcaveman    schedule 09.10.2012
comment
Я постараюсь добавить структуру проекта после того, как вернусь с обеда. Пока я не дойду до этого, я посмотрю, смогу ли я объяснить вещи немного лучше. Разница между моделью предметной области и логикой предметной области состоит в том, что модель предметной области - это всего лишь сущности, в которых логика предметной области, о которой я говорю, - это такие вещи, как сервисы предметной области и рабочие процессы, которые включают более чем одну сущность или не отображаются на объектах как поведение.   -  person user546077    schedule 09.10.2012
comment
Модуль для меня - это вертикальный срез системы. Наша система в основном представляет собой набор модулей, каждый из которых имеет подэлемент. Если вы подумали о MS Office как о приложении, Outlook был бы одним модулем, а Word - другим.   -  person user546077    schedule 09.10.2012
comment
Разница между DTO и интерфейсом и нашими объектами модуля домена заключается в том, что DTO - это немые объекты, которые передают данные между слоями (плоская модель), объекты домена богаты поведением и отношениями друг к другу, а интерфейсы будут просто абстракцией объекта домена, который клиенты (уровень представления) также могут выполнять привязку вместо прямой привязки к объектам домена (программа к интерфейсу). Я опубликую обновление структуры проекта, как только смогу. Спасибо   -  person user546077    schedule 09.10.2012


Ответы (1)


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

2) Это действительно вопрос предпочтения организации. Оба действительны. Твой выбор.

3) Другой вопрос о предпочтении организации. Лично я сначала организую свой код по ограниченному контексту. Затем у меня есть сущности и агрегированные корни непосредственно под ними. Затем у меня есть папки для перечислений, репозиториев (интерфейсов), служб (интерфейсов), спецификаций и значений. Пространства имен не отражают эту организационную структуру за пределами последней ограниченной папки контекста. Но, опять же, вы должны делать это так, как вам лучше всего подходит для вашего взгляда на код.

4) Это проблема реализации. Я лично разбиваю проблемы реализации на интерфейсы только в том случае, если я думаю, что есть большая вероятность, что мне придется поменять реализации в будущем. При этом я обычно организую свои вспомогательные библиотеки в определенные контексты инфраструктуры (например, MainContext.Web.MVC.Helpers или MainContext.Web.WebForms.Helpers.) Они редко меняются, и мне еще предстоит встретить экземпляр, в котором мне нужно было бы полностью отказаться от реализации.

5) Насколько я понимаю, вполне допустимо использовать интерфейсы вместо конкретных объектов для ваших доменных объектов. При этом мне еще предстоит столкнуться с ситуацией, когда мне потребовались бы разные реализации для объектов моего домена. Единственная причина, о которой я могу думать, это то, что вам нужно изменить бизнес-логику для одного приложения, но оставить старое приложение с использованием исходной бизнес-логики. Если ваши бизнес-объекты являются хорошими моделями для предметной области, я не могу понять, что вы действительно сталкиваетесь с этой проблемой, но я видел примеры, когда люди делают это просто ради абстракции. ИМХО, это не стоит дополнительных усилий по кодированию, но если это заставляет вас чувствовать себя хорошо внутри или вы получаете какую-то реальную выгоду (например, облегчение тестирования), нет никаких причин, по которым вы не можете абстрагироваться от сущностей своей предметной области. При этом доменные службы и репозитории обязательно должны иметь контракты, которые позволяют вам менять их реализации.

Ответ 5 основан на идее, что приложение - это тот, кто выбирает реализации. Если вы пытаетесь создать луковичную архитектуру, ваше приложение будет выбирать конкретные реализации для всего (репозитории, доменные службы и другие проблемы абстрактной реализации). Я не вижу причин, по которым он не может просто использовать агрегаты домена напрямую, поскольку они являются конкретным представлением вашей модели предметной области. (Примечание: все сущности должны быть инкапсулированы в агрегаты. Приложение никогда не должно иметь возможность удерживать ссылку на сущность, которая не является агрегатом в контексте)

person Aaron Hawkins    schedule 14.12.2012