#c# #entity-framework #design-patterns #domain-driven-design #onion-architecture
#c# #entity-framework #шаблоны проектирования #дизайн, управляемый доменом #onion-архитектура
Вопрос:
Я только начинаю работать с DDD и внедряю архитектуру Onion.
Я создаю систему приглашений, в которой суперпользователь может пригласить другого пользователя по электронной почте в свою компанию. Однако при создании приглашения я хочу убедиться, что пользователь еще не создан в системе. Я хочу сделать это, проверив, есть ли в базе данных какая-либо запись с этим электронным письмом. Я использую Entity Framework для обработки контекста базы данных.
И я создал репозиторий как для Invitation, так и для UserAccount, которые содержат методы поиска элементов на основе идентификатора.
Мне нужно использовать контекст БД, чтобы проверить, действительно ли приглашение все еще действует, но поскольку метод объявлен на уровне домена, я не могу понять, как это сделать, не нарушая шаблон проектирования. Уровень домена не должен ничего знать о уровне сохраняемости.
Я думал о внедрении IUserAccountRepository, а затем о выполнении требуемых методов для завершения метода Accept (), но я боюсь, что это неправильно.
Комментарии:
1.
DeriveAccount
должен выдавать исключение, если не удается создать учетную запись, поскольку пользователь уже существует. Вам действительно нужна еще одна избыточная, ненадежная проверка для этого?
Ответ №1:
Уровень домена не должен ничего знать о уровне сохраняемости.
Это верно — уровень домена не должен знать о постоянстве.
Но это ограничение не распространяется на прикладной уровень.
Другими словами, мы проектируем наш интерфейс модели предметной области таким образом, чтобы он «запрашивал» информацию, которая нам (может) понадобиться для успешного вычисления следующего состояния модели, и приложение сталкивается с проблемой выяснения, откуда поступает эта информация.
public UserAccount Accept(Guid userId, Boolean userExistsInDatabase)
Что вы увидите в некоторых проектах, так это то, что вместо передачи ответа на вопрос мы передадим возможность задавать вопрос, и пусть модель сама решает, следует ли задавать вопрос и что делать с ответом
public UserAccount Accept(Guid userId, Roster roster)
В этом случае Roster
будет интерфейс, определенный вашей моделью, который принимает некоторую часть информации, которая уже есть у модели, и сообщает некоторую другую часть информации, которую понимает ваша модель. Тогда ваше приложение будет предоставлять реализацию этого интерфейса при вызове метода.
Передача значений через границы немного более «чистая», поскольку коду модели не нужно ничего знать о режимах сбоя реестра — весь этот код вместо этого будет находиться на прикладном уровне.
Ответ №2:
Это нормально использовать контракты в ваших доменных службах.
«IUserAccountRepository» — это контракт, который мы создаем в домене, и служба домена не знает о реализации.
Так что не беспокойтесь о том, что это правильно