Ncqrs: Как создать событие, не имея совокупного корня
Учитывая, что у меня есть два ограниченных контекста:
- Fleet Mgt - простой поддерживающий поддомен на основе CRUD
- Продажи - это мой основной домен на основе CQRS
Когда в управлении автопарком происходит операция CRUD, должно быть опубликовано событие, отражающее операцию:
- AircraftCreated
- AircraftUpdated
- AircraftDeleted
- и т.п.
Эти события необходимы: а) для обновления различных таблиц индекса, необходимых в домене продаж, и б) для предоставления единого журнала аудита.
Вопрос: Есть ли простой способ хранить и публиковать эти события (на InProcessEventBus
Я не использую NSB здесь), не проходя через AggregateRoot
, что мне не нужно в простом контексте CRUD.
2 ответа
По словам Питера, основного участника Ncqrs, сделать это невозможно из коробки.
В этом сценарии я не хочу проходить всю церемонию создания и выполнения команды, а затем загружать агрегатный корень из хранилища событий, просто чтобы он отправил событие.
Поведение является простым CRUD, реализованным с использованием простейшего решения, которое в данном конкретном случае представляет собой формы поверх данных с использованием Entity Framework. Единственное, что мне нужно, - это событие, публикуемое после совершения транзакции.
Мое решение выглядит так:
// Abstract base class that provides a Unit Of Work
public abstract class EventPublisherMappedByConvention
: AggregateRootMappedByConvention
{
public void Raise(ISourcedEvent e)
{
var context = NcqrsEnvironment.Get<IUnitOfWorkFactory>()
.CreateUnitOfWork(e.EventIdentifier);
ApplyEvent(e);
context.Accept();
}
}
// Concrete implementation for my specific domain
// Note: The events only reflect the CRUD that's happened.
// The methods themselves can stay empty, state has been persisted through
// other means anyway.
public class FleetManagementEventSource : EventPublisherMappedByConvention
{
protected void OnAircraftTypeCreated(AircraftTypeCreated e) { }
protected void OnAircraftTypeUpdated(AircraftTypeUpdated e) { }
// ...
}
// This can be called from anywhere in my application, once the
// EF-based transaction has succeeded:
new FleetManagementEventSource().Raise(new AircraftTypeUpdated { ... });
Если вы хотите опубликовать событие о чем-то, это что-то, вероятно, является агрегированным корнем, потому что это внешне идентифицированный объект, представляющий собой группу интересов, в противном случае, почему вы хотите отслеживать их?
Помня об этом, вам не нужны индексные таблицы (я так понимаю, для запросов) в BC BC. Вы нуждаетесь в GUID Самолета и только поиски / соединения на стороне чтения.
Для аудита я просто добавил бы общее событие аудита через отражение в репозиториях / единицах работы.