Хотя «один агрегат на транзакцию» является правилом , это, вероятно, не убьет вас из-за прагматичности и игнорирования его в определенных ситуациях.На самом деле, я бы сказал, что будут случаи, когда это просто не практично или даже невозможно каким-либо иным способом.
При этом, безусловно, вы должны сделать все возможное, чтобы придерживаться этого принципа.,Ваш случай не редкость.Например, на ум приходят уровни запасов и авиабилеты (на самом деле уровни запасов).
Единственный способ разделить операции на два отдельных этапа - это отслеживать процесс .Для этого вам нужен менеджер процессов, и вам даже может понадобиться обмен сообщениями, но это все в порядке.
Чтобы обойти проблему, вам нужно «зарезервировать» создание на первом шаге, используя, скажем, некоторые идентификатор корреляции .Затем его можно сохранить в транзакции A:
// begin tx (application layer)
if (A.Reserve(id))
{
// we're good
bus.Send(new RegisterBCommand
{
Id = id,
TheIdForA = theId
// other properties
}); // perhaps using Shuttle.Esb
}
// commit tx (application layer)
На следующем шаге будет зарегистрирована сущность B и, возможно, будет опубликована BRegisteredEvent
, которая может продолжить процесс.
Еще один момент: вы обычнобудет иметь A.CreateB()
только если A и B живут в одном и том же ограниченном контексте.Другим способом достижения чего-то слегка похожего было бы использование ограниченного интеграцией контекста (скажем, вашей оркестрации BC), а затем использование CreateB()
в качестве метода расширения для A, где A и B находятся в отдельных BC, но уровень оркестровки использует оба домена,Другой путь - простой завод или просто добавление его в службу приложения / домена.