Reputation: 5256
Let's say I have the following relationship ):
Aggregate A (contains E1, E2, E4)
- Entity of type E1
- Entity of type E2 (contains E3)
- Sub-entity of type E3
- Entity of type E4
All entities implement the following signature:
fun handleCommand(command: Command): List<Event> // returns a list of events that can be applied on itself
fun handleEvent(event: Event): Entity // returns itself with the new event applied
When handling a command on say E4
, that should logically cause some side-effect (events) on E2, what is the best-practice? Note that this should not be confused with sagas, but this is rather a general question about how resulting side-effects on parent entities should be generated when handling a command on a child entity.
Upvotes: 1
Views: 465
Reputation: 57367
The literature is pretty weak on non-trivial aggregates.
When handling a command on say E4, that should logically cause some side-effect (events) on E2, what is the best-practice?
Probably the most important thing to note is this: cause and effect is part of the business logic, not part of the state. We don't need to consider the hollistic interconnectedness of all things when we are integrating events, because the other things are written down elsewhere.
When we are reconstituting entities from their histories, the business rules no longer apply - each entity state is derived from its own events in isolation.
Because the entities are all part of the same aggregate, their events should be written together, to a single persistent storage in a single transaction.
Because the entity states are logically isolated from one another, the order of events doesn't particularly matter - entity behaviors are concurrent. Each entity should see its own events in the "right" order, but it doesn't particularly matter is entity E4 is reconstituted from its events before or after E2.
(Order of events in a single entity may still be relevant.)
Upvotes: 1
Reputation: 2305
This is the point of an Aggregate. It would coordinate this process. External code would not be able to issue a command directly on E4 as it would be encapsulated in the Aggregate. Rather the command would be routed to the aggregate and the aggregate would issue and coordinate the process internally.
Hope that helps
Upvotes: 2