В вашем вопросе отсутствует некоторый контекст, например, каков сценарий пользователя, который приводит к этому событию, и в каком состоянии вы начинаете? Если бы вы писали тесты BDD для этого случая, как бы они выглядели? Знание этого очень поможет в ответе на ваш вопрос.
Способ решения проблемы связи книги с автором зависит от домена. Во-первых, мы предполагаем, что для вашего домена имеет смысл иметь агрегат для автора и агрегат для книги, например, если бы я писал систему библиотек, я сомневаюсь, что у меня будет агрегат для авторов, так как меня не волнует Автор без его / ее книги, что меня волнует, так это книги.
Что касается отсутствия получателей, то стоит упомянуть, что у агрегатных корней нет получателей из-за предпочтения стиля ООП сказать-не-спрашивать . Однако вы можете сказать одному AR сделать что-то, что затем скажет что-то другому AR, если вам нужно. Отчасти важно то, что AR рассказывает другим о себе, а не пишет код, в котором вы спрашиваете , а затем передаете его.
Наконец, я должен спросить, почему у вас нет идентификатора автора во время добавления книги? Откуда ты вообще знаешь, кто автор? Я хотел бы предположить, что вы могли бы просто сделать следующее (мой код предполагает, что вы используете свободный интерфейс для создания AR, но вы можете заменить фабрики, конструкторы, что вы используете):
CreateNew.Book()
.ForAuthor(command.AuthorId)
.WithContent(command.Content);
Теперь, возможно, сценарий заключается в том, что вы добавляете книгу вместе с новым автором. Я бы обработал это как две отдельные команды (которые могут иметь больше смысла для вашего домена), или обработал бы команду следующим образом:
var author = CreateNew.Author()
.WithName(command.AuthorName);
var book = CreateNew.Book()
.ForAuthor(author.Id)
.WithContent(command.Content);
Возможно, проблема в том, что у вас нет получателя для совокупного корневого идентификатора, что я не считаю необходимым или распространенным. Однако, если для вас важна инкапсуляция Id, или для вашего события BookAdded требуется больше информации об авторе, чем может предоставить Id, тогда вы можете сделать что-то вроде этого:
var author = CreateNew.Author()
.WithName(command.AuthorName);
var book = author.AddBook(command.Content);
// Adds a new book belonging to this Author
public Book AddBook(BookContent content) {
var book = CreateNew.Book()
.ForAuthor(this.Id)
.WithContent(command.Content);
}
Здесь мы говорим автору добавить книгу, после чего он создает совокупный корень для книги и передает ее идентификатор в книгу. Тогда у нас может быть событие BookAddedForAuthor, которое будет иметь идентификатор автора.
Последний имеет свои недостатки, но создает команду, которая должна действовать через несколько совокупных корней. Как можно больше я попытался бы выяснить, почему первый пример не работает для вас.
Кроме того, я не могу не подчеркнуть, как реализация, которую вы ищете, продиктована вашим конкретным контекстом домена.