Open meiedomi opened 3 years ago
Hello @meiedomi sorry for the late reply
I've reflected about these as well. While dispatching command (defined in application layer) inside saga state (domain layer) can effectively appear as a violation of dependency inversion principle, what I've tried to do is to not add domain logic in the saga manager, leaving it only the responsibility of acting as "glue code" between the events and the core logic.
An alternative could be returning a desired state from the saga state model (eg using an enum) and making the association desired state/command in the saga manager
roughly, something like that (in pseudocode)
onEventReceived(event) {
state = sagaState.checkSomething(event.associationData)
if (state == SOME_STATE) {
dispatchCommand(new SomeCommand())
}
}
And what about you? how would you address this aspect? 🙂
Hey @cingaldi what you suggest would be one way of eliminating the asymmetry between commands and events. The other way would have been to shovel the events right into the saga state and thus into the domain layer.
So inside your saga manager, you could just pass the event down into the saga state:
onEventReceived(fooEvent) {
sagaState.handleFooEvent(fooEvent.property1, fooEvent.property2);
...
}
Note that I wouldn't pass the fooEvent
DTO directly into the handleFooEvent
method, as the former lives in the app layer while the latter is defined in the domain layer. Instead of passing the individual properties, I could have used a domain-specific event type and mapped from the fooEvent
to that one first.
This way, both the events and commands reside in the saga state. The manager only translates, without changing semantics or having to know anything about the domain. If you think about it: In your original solution, if the manager receives an event and then calls some saga state method, how does it know which method to call? How does it know how to translate the event into a change in the saga state? That by itself could be considered domain logic.
Something seems to be odd here. You host the logic to create commands inside the saga state entity (domain layer), but you map incoming events to follow-up commands in the saga manager (application layer). Shouldn‘t both of these things be part of the state entity such that everything business-related is in one place and no leakage happens?
I'd appreciate your opinion about this objection. ;)