2015-08-28 2 views
1

Я использую CQRS с event-sourcing. У меня есть один объект eg.Form с entityId. Теперь мне нужно отправить команду копирования (CommandName: CopyForm, EventName: FormCopied) на эту сущность. Итак, вся эта форма должна быть скопирована и иметь разные entityId.Скопируйте весь объект с помощью EntityId в CQRS с eventSourcing

Для этого я отправляю entityId формы с командой CopyForm, которую необходимо скопировать. Вся форма загружается из хранилища событий, а при поднятии события я поднимаю событие как FormAdded вместо FormCopied, которое добавит новую форму точно так же, как и исходную форму, которую мы загружаем из eventStore, и просто устанавливаем новый entityId. Но проблема здесь - это событие для той же формы, которую я копирую вместо скопированной формы. Мои рамки не позволяют изменять entityId. Framework по умолчанию set entityId команды, которую я поднимаю для исходной формы и события, создается для исходной формы с одним и тем же entityId.

Есть ли лучший способ выполнять функции копирования для объекта в CQRS с помощью Event-Sourcing?

ответ

1

Ответ Брайана хороший, но немного неполный.

В системе поиска событий служба управления доменами должна иметь возможность регидратировать сущности из журнала событий. Независимо от резервного хранилища журнала событий, он, скорее всего, будет проиндексирован EntityID, а сущности будут регидратированы, вытягивая все события для данного EntityID из хранилища резервных данных. Следовательно, для события FormCopied должно быть стандартное поле EntityId, не так ли?

Мы могли бы использовать следующее:

FormCopied { EntityId, OriginalEntityId } 

Это лишь немного отличается от ответа Брайана, в том, что она позволяет хранилище событий, который индексируется EntityId.

Кажется правильным, что событие FormCopied будет частью потока, который будет регидратировать новый объект Form. Но все еще есть проблемы. Например, представьте, что следующий наш пользователь попытается добавить новое поле в свою форму. Вот, вероятно, следующая команда:

AddFieldToForm { EntityId, NewField } 

Теперь представьте также, что эта «форма» Entity имеет некоторые бизнес-правила, чтобы проверить, как сущности часто. Командная служба захочет загрузить новый объект «Form», чтобы проверить бизнес-правила, поэтому он попытается перевести сущность «Форма» из журнала событий. Мы вытягиваем журнал событий и находим только одно событие.

FormCopied { EntityId, OriginalEntityId } 

Так что теперь мы должны вернуться в журнал событий, а также тянуть поток событий для OriginalEntityId для того, чтобы получить полностью разведенной копию нового объекта.Есть, по крайней мере 2 способа вы можете сделать это:

  1. На самом деле потянув поток событий для OriginalEntityId, а затем воспроизведение его, как будто это события произошли от этого нового объекта - или -
  2. Загрузив вверх оригинал объект, который соответствует OriginalEntityId и копирует его свойства один за другим на новый объект.

Выбранный вами вариант будет зависеть от возможностей вашего каркаса.

+0

Что делать, если мы создаем событие FormAdded вместо FormCopied? Почему нам по-прежнему не нужно поднимать каждое событие отдельно, которое произошло ранее для исходного объекта? –

1

Ваш случай кажется немного странным, но в любом случае самым простым методом, который я могу представить, является получение потока событий в форме, дублирование и замена идентификатора объекта в копиях (вы можете это сделать, потому что события - это простые данные структуры). Затем сохраните и опубликуйте новый поток событий. Если копируемый факт имеет значение домена, событие FormAdded может иметь свойство IsCopied.

4

Опубликовать событие с указанием новый факт:

FormCopied { OriginalEntityId, NewEntityId } 

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

+0

Версия оригинального объекта также должна быть включена: o) –

+0

@SirRufo: Событие 'FormCopied' сообщает нам момент, когда оригинал был скопирован, предоставив нам достаточно информации для продолжения без введения дополнительных данных. Приобретение событий велико, потому что вы можете воспользоваться временными отношениями, которые часто теряются в n-уровневых системах. –