Предположим, у меня есть агрегат, который для некоторой операции требует существования другого агрегата.Давайте предположим, что у меня есть car
и garage
.Может существовать команда с именем ParkInGarage
, которая выглядит следующим образом:
public class ParkInGarage {
@TargetAggregateIdentifier
public final UUID carId;
public final Garage garage;
//... constructor omitted
}
У меня чтение , что для проверки существования агрегата рекомендуется использовать загруженный файл.агрегировать в командах, поскольку это уже подразумевает его существование (в отличие от передачи garageId
).
Теперь, когда юнит-тестирование Car
с использованием приборов Аксона , я не могу просто создать экземплярмой Garage
, сказав new Garage(buildGarageCmd)
.Будет сказано:
java.lang.IllegalStateException: Невозможно запросить текущий Scope, если ни один не активен
, так как инфраструктура не была настроена.Как бы я протестировал такой случай, или я должен по-другому проектировать агрегат?
Абстрактный, реальный пример
Корень агрегата, с которым я работаю, может иметь ссылку на себя, чтобы сформироватьдревовидная структура указанного совокупного корня.Давайте назовем это Node
.
@Aggregate
public class Node {
private Node parentNode;
}
После создания я могу передать Optional<Node>
в качестве родителя или установить родителя позже, используя отдельную команду.Вопрос о том, должен ли родитель быть определен как экземпляр или по идентификатору, является частью вопроса.
public class AttachNodeCmd {
@TargetAggregateIdentifier
public final UUID nodeId;
public final Optional<Node> parentNode;
}
В обработчике команд мне нужно проверить, будет ли присоединение узла к данному родителю вводить цикл (структурадолжно быть деревом, а не общим графом).
@CommandHandler
public Node(AttachNodeCmd command) {
if (command.parentNode.isPresent()) {
Node currentNode = command.parentNode.get();
while (currentNode != null) {
if (currentNode.equals(this)) throw new RecursionException();
currentNode = currentNode.parentNode.orElse(null);
}
}
//Accept the command by applying() an Event
}
В какой-то момент родительский экземпляр должен быть создан для выполнения этих проверок.Это можно сделать либо путем предоставления экземпляра агрегата в команде (не рекомендуется), либо путем предоставления Repository<Node>
и nodeId
для обработчика команды, который является самим агрегатом и также не рекомендуется.В настоящее время я не вижу правильного способа сделать это и дальше по дороге, чтобы проверить это.