Я немного читал об DDD, и меня смущает, как это будет соответствовать при использовании ORM, например, NHibernate.
Сейчас у меня есть приложение .NET MVC с довольно "толстым"контроллеры, и я пытаюсь выяснить, как лучше это исправить.Перемещение этой бизнес-логики на уровень модели было бы лучшим способом сделать это, но я не уверен, как это сделать.
Мое приложение настроено так, что сеанс NHibernate управляется HttpModule (получает сеанс/ транзакция из моего пути), которая используется репозиториями, которые возвращают объекты сущности (думаю, S # arp arch ... оказывается действительно дублирует большую часть их функциональности в этом).Эти репозитории используются DataServices, которые в настоящее время являются просто обертками вокруг репозиториев (взаимно-однозначное сопоставление между ними, например, UserDataService принимает UserRepository или фактически Repository).Эти DataServices прямо сейчас гарантируют, что аннотации данных, украшающие классы сущностей, проверяются при сохранении / обновлении.
Таким образом, мои сущности на самом деле являются просто объектами данных, но не содержат никакой реальной логики.Хотя я мог бы поместить некоторые вещи в классы сущностей (например, метод «Утвердить»), когда для этого действия необходимо выполнить что-то вроде отправки электронного письма или прикосновения к другим не связанным объектам, или, например, проверить, чтобы увидеть,есть пользователи, которые имеют одинаковую электронную почту перед утверждением и т. д., тогда сущность будет нуждаться в доступе к другим репозиториям и т. д. Внедрение их с помощью IoC не будет работать с NHibernate, поэтому вам придется использовать фабрикушаблон, который я предполагаю, чтобы получить это.Хотя я не понимаю, как вы будете насмехаться над ними в тестах.
Так что следующим наиболее логичным способом сделать это, я думаю, было бы, по сути, иметь службу на контроллер и извлекать всю работув настоящее время выполняется в контроллере в методы в каждой службе.Я думаю, что это противоречит идее DDD, поскольку логика больше не содержится в реальных объектах модели.
Другой способ взглянуть на это, как я полагаю, заключается в том, что каждый из этих сервисов формируетединая модель с объектом данных, с которым он работает (разделение полей хранения данных и логики, которая на нем работает), но я просто хотел посмотреть, что делают другие, чтобы решить проблему «толстого контроллера» с DDD при использовании ORM, напримерNHibernate, который работает, возвращая заполненные объекты данных, и модель хранилища.
Обновлено Я думаю, моя проблема в том, как я смотрю на это: NHibernate, кажется, помещает бизнес-объекты (сущности) вдно стека, на которое затем действуют репозитории.Репозитории используются сервисами, которые могут использовать несколько репозиториев и другие сервисы (электронная почта, доступ к файлам) для выполнения каких-либо задач.Т.е.: App> Services> Repositories> Business Objects
Чистый подход DDD, о котором я читаю, кажется, отражает смещение Active Record, когда функции CRUD существуют в бизнес-объектах (это я вызываю User.Delete напрямуювместо Repository.Delete from service), а фактический бизнес-объект обрабатывает логику действий, которые необходимо выполнить в этом случае (например, отправка электронной почты пользователю, удаление принадлежащих ему файлов и т. д.).Т.е. App> (Services)> Business Objects> Repositories
С NHibernate, мне кажется, было бы лучше использовать первый подход с учетом способа NHibernate, и я ищу подтверждение моей логики.Или, если я просто запутался, некоторые пояснения о том, как этот многоуровневый подход должен работать.Насколько я понимаю, если у меня есть метод «Утвердить», который обновляет модель User, сохраняет ее и, скажем, отправляет по электронной почте нескольким людям, этот метод должен использовать объект сущности User, но для обеспечения надлежащего IoC, чтобы я могВнедрите MessagingService, мне нужно сделать это на моем уровне обслуживания, а не на объекте User.
С точки зрения «множественного пользовательского интерфейса» это имеет смысл, так как логика выполнения работы берется из моего уровня пользовательского интерфейса (MVC) и помещается в эти службы ... но я, по сути, просто учитываю логику другому классу вместо того, чтобы делать это непосредственно в контроллере, и если я не собираюсь вовлекать какой-либо другой пользовательский интерфейс, то я просто обменял «толстый контроллер» на «толстый сервис», так как сервис по сути собирается инкапсулировать метод в действие контроллера для выполнения его работы.