Через некоторое время я нашел решение, на основании голосов, которые, как я полагаю, другие сталкиваются с той же проблемой, вот решение:
Вопрос: можем ли мы вызвать явный вызов для событий домена?
Ответ: Да, можем. В SpringBoot
мы можем использовать / Autowire
интерфейс ApplicationEventPublisher
, а затем вызвать метод publishEvent(event)
.
Если вы создаете отдельный класс для коллекции Db и Aggregate, вам нужно будет раскрыть свой DomainEvents
и метод для ClearingDomainEvents
в вашей совокупности, поскольку AbstractAggregateRoot<T>
имеет эти методы как protected
. Ниже приведен пример создания события при создании:
public class MyAggregateRootClass extends AbstractAggregateRoot<MyAggregateRootClass>
{
public MyAggregateRootClass(String property1, String property2) {
// set the fields here
registerEvent(new MyAggregateRootCreated(someArgs));
}
public Collection<Object> getDomainEvents() {
return super.domainEvents();
}
public void clearDomainEvents() {
super.clearDomainEvents();
}
}
Код репозитория будет выглядеть так:
@Repository
@RequiredArgsConstructor // using lombok here, you can create a constructor if you want
public class MyAggregateRepository {
private final ApplicationEventPublisher eventPublisher;
private final AggregateMongoRepository repository;
public void save(MyAggregateRootClass aggToSave) {
AggregateDao convertedAgg = new AggregateDao(aggToSave);
repository.save(convertedAgg);
// raise all the domain events
for (Object event : aggToSave.getDomainEvents())
eventPublisher.publishEvent(event);
// clear them since all events have been raised
aggToSave.clearDomainEvents();
}
}
Значит ли это, что обычно мы не должны создавать два разных класса, один как AggregateRoot
, а другой как класс документа для хранения совокупных корней в mongoDB
?
Ответ : Нет, это не значит. Целью DDD
было бы отделить infrastructure
от Domain
и сохранить Domain
агности c всего кода инфраструктуры. Если они оба одинаковы, то влияние ниже показано:
- Наличие аннотации
@Document
на вашем Aggregate Class
заставит вас изменить Domain
, если вы переключаете фреймворки или меняете местами Mongodb
с SQL
. - В будущем, если ваша схема БД потребуется изменить, вам придется либо также изменить свой совокупный класс, либо вам придется настроить классы адаптеров.
- Поскольку домен должен меняться только в случае изменения бизнес-требований, а не из-за
infrastructure dependencies
, проникновение из infrastructure annotations
в AggregateRoot
было бы не лучшим способом
Итак, когда вы действительно можете просто обойтись без использования одного и того же класса для Aggregate и Db Collection?
Если вы действительно хотите сохранить простоту и использовать один и тот же класс для обоих, а не создавать отдельный класс, убедитесь, что вы уверены в следующем:
- Если вы абсолютно уверен, что вы никогда не собираетесь переключать БД или менять фреймворки.
- У вас простая модель домена, и вам не нужно хранить
Entities
из Aggregate
в отдельной коллекции, и вы есть нет возможности, что эти Entities
когда-либо вырастут в свои Aggregates
В конце концов, это зависит от обстоятельств. Не стесняйтесь оставлять комментарии, и я постараюсь ответить на все из них, довольно активно в стеке.