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 Car
s 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
Race
s 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!