CQRS / EventStore: как проверить, существует ли агрегат? - PullRequest
0 голосов
/ 31 января 2012

В настоящее время я использую EventStore J Oliver и хочу узнать, как я могу проверить, существует ли агрегат, когда я выполняю свой вызов (GetById (Guid id))??

Следуя принципам работы CQRS, я долженЗапрашивает чтение базы данных или я должен как-то выяснить, есть ли соответствующий агрегат в EventStore?

TIA

JD

Ответы [ 2 ]

3 голосов
/ 31 января 2012

Как работает EventStore, вы создадите новый поток (Aggregate root), если поток не найден.

Проверьте эту строку: https://github.com/joliver/CommonDomain/blob/master/src/proj/CommonDomain.Persistence.EventStore/EventStoreRepository.cs#L53

Вызывает этот метод в Магазине: https://github.com/joliver/EventStore/blob/master/src/proj/EventStore.Core/OptimisticEventStore.cs#L45

Который вызывает этот конструктор: https://github.com/joliver/EventStore/blob/master/src/proj/EventStore.Core/OptimisticEventStream.cs#L27

Эффект состоит в том, что он либо заполняет поток с помощью Commits, который он нашел в постоянстве, либо, если ничего не найдено, он ничего не делает и возвращает новый поток.

Однако вам не нужно задавать себе этот вопрос. Команда должна быть проверена перед отправкой. Используйте ваши модели чтения для проверки команды перед ее отправкой.

Кроме того, команда вместе с корневым состоянием агрегирования должна содержать достаточно информации для принятия решения в домене. В основном это означает, что вы должны быть уверены в состоянии домена, прежде чем отправлять свои команды, чтобы избежать исключений в домене. И вы можете использовать для этого модель чтения.

Обновление в ответ на комментарий Mauros:

У вас проблема с параллелизмом. Вы можете решить эту проблему, используя метод, используемый в периодически подключаемых системах, который объединяется. Что вы можете сделать, это сохранить ревизию Stream в модели чтения, чтобы вы знали, на какую ревизию AR вы воздействовали. Затем, когда команда обрабатывается, вы знаете, действовали ли вы в старом состоянии АР.

Если ревизия AR выше, чем та, которую приносит команда, вы можете либо отклонить команду как ошибку (пессимистический параллелизм), либо вы можете попытаться объединить изменения.

Это можно сделать, посмотрев на события, вызванные ревизией в команде, вплоть до текущего состояния. Затем вызовите поведение, которое должна была выполнить команда, и посмотрите на события, созданные этим поведением, и сравните две коллекции событий. Если нет конфликтующих событий, вы можете зафиксировать вновь созданные события в хранилище. Если есть конфликты, вы можете выдать исключение параллелизма.

Я думаю, что вы лучше всего решаете проблему параллелизма такого типа.

Поиск слияния событий для получения дополнительной информации.

1 голос
/ 31 января 2012

Полагаю, вы на самом деле имеете в виду IRepository.GetById() в проекте CommonDomain JOliver?

Когда вы вызываете GetById с совокупным корневым идентификатором, которого нет в хранилище событий, хранилище выдаст вам новыйагрегатный объект с .Version == 0 и .Id == Guid.Empty.Я только что создал свой собственный производный репозиторий, который обнаруживает это условие и возвращает вместо него нуль:

public override TAggregate GetById<TAggregate>(Guid id, int versionToLoad)
{
    var aggregate = base.GetById<TAggregate>(id, versionToLoad);
    return aggregate.Version > 0 ? aggregate : null;
}

Это может быть неправильным способом (см. Ответ Микаэля), но пока он работает нормально для меня.

...