I'm in a scenario where, when a certain command is applied on an aggregate, I have to
- change the state of the aggregate itself
- if ALL related aggregates are in the same state, then notify the world outside
here is an example (in pseudocode)
finishRace(raceId, carId) cars = repository.findCarsByRaceId(raceId) cars.get(carId).finishRace() repository.save(cars.get(carId)) if(allCarsHaveFinished()) publishEvent(RaceFinishedEvent())
It is clear to me that this logic belongs to a domain service, since it is related with multiple aggregates. Usually domain events represent a side effect of an operation of a single aggregate, but here the side effect has to be somehow "filtered" based on the state of other aggregates
Another (elegant) option could be to introduce a
Race aggregate root and make single
Cars as child entities, so that I can check invariants inside the Race
finishRace(raceId, carId) race = repository.findRaceById(raceId) race.finishForCar(carId) repository.save(race)
but it seems to not be a good option since
- in general, there can be a lot of cars in a single race, so the Race aggregate would be quite big
- in my specific case, a car can switch between different races So I should change two
Races time everytime this event happens
So coming back, the simplest solution would be to publish an event from a domain service. Is this considered a good practice? there are hidden downsides that I'm not seeing?
Thanks for the answers!