Учитывая следующие архитектурные изменения и нуждаемся в некотором совете (доменные сущности, DTO, агрегаты)
Около года назад я создал решение, состоящее из уровня представления ASP.Net MVC 3 (сейчас), уровня приложений, уровня домена и уровня инфраструктуры (пересекающиеся данные и данные). Я решил оставить модель предметной области в отдельном проекте от логики предметной области и использовать непринужденный подход к уровню представления, передавая доменные сущности вместо DTO, поскольку у нас действительно только один интерфейс на данный момент.
В ближайшее время мы собираемся обслуживать распределенный слой, в дополнение к нашему основному веб-сайту, и я буду использовать там DTO, но я также рассматриваю возможность использования DTO на основном веб-сайте. Мне также интересно, стоит ли мне прерывать код структуры на уровне домена (IRepository, IUnitOfWork, супертипы объектов Entity/Value и т. Д.). Ну что ж, позвольте мне перечислить вопросы, по которым мне нужна обратная связь:
1) Я был довольно усердным в том, что у меня нет анемичной модели предметной области, а также следил за поведением, характерным для проблем презентации. Большинство бизнес-вычислений, которые необходимы, выполняются на объектах домена. Хорошо ли, чтобы уровень представления вызывал это поведение напрямую, или он должен вместо этого вызывать службу приложения, которая затем вызывает объекты домена? Это подсказало бы мне, что нет никакой причины, чтобы уровень представления знал о объектах домена и вместо этого мог использовать DTO. В качестве альтернативы, я мог бы заставить DTO разоблачить это поведение, но потом я чувствую, что граблю доменные объекты. Итак, я думаю, что есть 3 варианта (богатые доменные объекты, вызываемые напрямую, сервисный уровень или dto с поведением), что лучше?
2) Прямо сейчас у меня есть доменный проект, который имеет доменные сервисы, спецификации и логику и координируется прикладным уровнем и отдельным проектом для доменной модели (используется на уровне представления и прикладном уровне). У меня также есть инфраструктурные интерфейсы для общего репозитория и единицы работы. Должен ли я разбить фреймворк на отдельный проект и объединить остальное в один проект?
3) Я хочу реорганизовать свой уровень домена в совокупности, сейчас вся модель домена организована по модулям, в основном все типы для каждого модуля находятся в одном пространстве имен. Было бы лучше организовать организации, объекты стоимости, услуги и другие вещи по совокупности?
4) Должен ли я использовать шаблон Раздельный интерфейс для инфраструктурных сервисов, которые в основном являются типами библиотек помощников. Например, объекты конфигурации или валидаторы валидации? Какая польза от этого?
5) Наконец, не так много примеров, которые я видел, использовали интерфейсы для сущностей домена. Почти каждый объект, который у меня есть, я предпочитаю передавать по интерфейсам по причинам зависимости, и это значительно облегчает тестирование. Допустимо ли использовать интерфейсы вместо бетонов? Я должен упомянуть, что мы используем EF 4.3.1 (скоро для обновления до последней версии), и я, кажется, помню, что у EF была проблема с использованием интерфейсов или чего-то еще. Должен ли я выставлять интерфейсы вместо доменных сущностей?
Заранее большое спасибо.
Структура проекта:
Presentation.Web | | | заявка | | | Domain.Model - Домен (Инфраструктура. Данные, Инфраструктура. Ядро, Инфраструктура. Безопасность)
Объяснение: Presentation.Web (веб-проект MVC3)
Приложение - Сервисный уровень, который управляет уровнем домена и отвечает на запросы от уровня представления (получите это обновление). Это организовано модулем, например, если бы у меня был модуль клиента, у меня был бы Application.Customer, и в нем были бы все службы приложений.
Домен - содержит доменные службы, спецификации, расчеты и другую доменную логику, которая не отображается как поведение на объектах домена. Например, вычисление, которое включает в себя несколько сущностей домена, представленных в качестве службы домена для вызова на уровне приложений. - Также содержит код платформы для спецификации инфраструктуры и основные интерфейсы для общего репозитория и шаблона единицы работы.
Domain.Model - содержит доменные сущности и перечисления. Организовано по модулю. Например, если у меня может быть клиентский модуль, в котором есть объект-клиент, объект-заказчик и т. Д. Это отделено от проекта домена, так что объекты могут использоваться на уровне приложений и презентаций.
Infrastructure.Security - Инфраструктура безопасности для аутентификации и авторизации
Infrastructure.Core - сквозной материал, используемый несколькими уровнями (валидаторы, ведение журнала, конфигурация, расширения, IoC, электронная почта и т. Д.). Большинство проектов зависят от интерфейсов в этом проекте (кроме domain.model) для сервисов инфраструктуры.
Infrastructure.Data - Реализация репозитория через LINQ и EF 4.3.1, уровень отображения, Реализация единицы работы. Интерфейсы находятся в проекте Домена (шаблон отдельных интерфейсов)
1 ответ
1) Сначала определите, действительно ли вашему основному веб-сайту нужно использовать прикладной уровень. ИМХО, если ваши прикладные службы и ваш основной веб-сайт находятся на одном веб-сервере, вам следует оценить, стоит ли потенциальная потеря производительности, если ваш основной веб-сайт вызывает методы сервера приложений, когда он может вызывать объекты домена напрямую. Однако, если ваш сервер приложений определенно находится на другом сервере, то да, вы должны заставить сервер приложений вызывать ваши доменные объекты и передавать только DTO между ним и любыми уровнями представления, которые у вас могут быть, включая ваш основной веб-сайт.
2) Это действительно вопрос о предпочтении организации. Оба действительны. Твой выбор.
3) Еще один вопрос о предпочтении организации. Лично я сначала организую свой код по ограниченному контексту. Тогда у меня есть сущности и совокупные корни прямо под ними. Затем у меня есть папки для перечислений, репозиториев (интерфейсов), сервисов (интерфейсов), спецификаций и значений. Пространства имен не отражают эту организационную структуру после последней ограниченной контекстной папки. Но, опять же, вы должны делать это так, чтобы лучше всего подходить к тому, как вы смотрите на код.
4) Это проблема реализации. Лично я разбиваю проблемы реализации на интерфейсы только в том случае, если думаю, что есть хорошая вероятность, что мне понадобится поменять реализацию в будущем. При этом я обычно организую свои вспомогательные библиотеки в определенные контексты инфраструктуры (например, MainContext.Web.MVC.Helpers или MainContext.Web.WebForms.Helpers.) Они редко меняются, и мне еще не приходилось сталкиваться с экземпляром, где мне нужно было поменяйте местами реализации полностью.
5) Насколько я понимаю, для ваших доменных сущностей вполне допустимо использовать интерфейсы вместо бетонов. При этом мне еще предстоит столкнуться с ситуацией, когда мне потребовались разные реализации для моих доменных сущностей. Единственная причина, о которой я могу думать, это то, что вам нужно было изменить бизнес-логику для одного приложения, но оставить старое приложение, используя оригинальную бизнес-логику. Если ваши бизнес-объекты являются хорошими моделями для домена, я не могу понять, что вы на самом деле столкнулись с этой проблемой, но я видел примеры, когда люди делают это просто ради абстракции. ИМХО, это не стоит дополнительных усилий по написанию кода, но если вы чувствуете себя хорошо внутри или получаете какую-то реальную выгоду (например, облегчаете тестирование), нет никаких причин, по которым вы не можете абстрагировать свои доменные сущности. При этом доменные службы и репозитории обязательно должны иметь контракты, которые позволяют вам менять их реализации.
Ответ 5 вытекает из идеи, что приложение - это тот, кто выбирает реализации. Если вы пытаетесь достичь луковой архитектуры, тогда ваше приложение будет выбирать конкретные реализации для всего (репозитории, доменные службы и другие абстрактные проблемы реализации). Я не вижу причин, по которым он не может просто использовать доменные агрегаты напрямую, поскольку они являются конкретным представлением вашей доменной модели. (Примечание. Все объекты должны быть инкапсулированы в агрегаты. Приложение никогда не должно содержать ссылку на объект, который не является агрегатом в контексте)