问题
I am trying to wrap my head around Saga's using Jonathan Olivers EventStore and CommonDomain. I understand how Aggregates are working with the CommonDomain/EventStore but I am stuck on grasping Saga usage. I have read both of Jonathan's Saga's with Event Sourcing Part I & II but sill lost in actual implementation
1) More of observation, when persisting the saga the EventStore is utilizing the Headers to persist the Saga and Commands that need to be sent out and it looks like the Payload is storing the Event that triggered the Saga to "wake up". Wondering reasons for this. Would we never want to store individual commands vs having them all in the header?
1) It seems like the Event that triggered the Saga gets replayed multiple times since the "Transition" method in SagaBase always re-adds the event to uncommitted collection. (Unlike ARs that have an internal Apply method vs public Domain method). Maybe I am not using the Transition method properly
2) Typically the bus that you use with the EventStore will publish Events (I implemented IPublishMessages). If I need my Saga to publish a command there does not seem to be a Send option. Do I need to parse the Headers to grab the commands myself?
I am thinking I am using the CommonDomain / EventStore incorrectly as working with Aggregates was easy but Saga's seem "incomplete" to me. I am assuming its because I am not doing it correctly. Still very new to CQRS. Does anyone have a working example of Saga's using J Olivers Common Domain / Event Store? I think that would clear things up considerably.
[EDIT] I think I figured it out but would like some input. Saga's really should not be publishing events. They send out commands. Thus on the publish side of things for the EventStore (IPublishMessages) I should first be checking the type of message (AggregateType vs SagaType) For AggregateTypes I can publish Events but for SagaTypes only publish the commands (found in Header). This eliminates the same event (say OrderSubmittedEvent) that triggers the creation of the Saga to not publish it again when persisting the saga.
回答1:
The commands are put in the headers to be sent on the bus. The EventStore is concerned with the storage of events so the events that caused saga transitions are persisted. Later, when the saga is loaded from the event stream, the events will be passed to the saga's transition method to bring it to the current state.
The transition method serves a dual purpose in the saga implementation. Transition is called to handle incoming messages and to load the saga from peristence. In SagaEventStoreRepository.BuildSaga ClearUncomittedEvents and ClearUndispatchedMessages are called on the saga after the current state is built up thus avoiding duplicate event and command processing.
I haven't personally done this but I would use a separate EventStore instance for my sagas. This would allow for the usage of a separate IPublishMessages implementation to take the commands from the event headers and send them.
来源:https://stackoverflow.com/questions/6891990/j-olivers-event-store-saga-help