A set of abstractions for implementing the Saga pattern.
$ dotnet add package EventDriven.Sagas.DependencyInjectionAbstractions and reference architecture for implementing the Saga pattern to orchestrate atomic operations which span multiple services.
docker run --name mongo -d -p 27017:27017 -v /tmp/mongo/data:/data/db mongoAddSaga service collection extension methods.SagaConfigurationDto containing Create Order Saga steps, actions and commands.CreateOrderSaga with dispatchers, commands, handlers and evaluators for orchestrating a saga with updates that span multiple services.The purpose of the Saga pattern is to enable atomic operations which span multiple microservices, each of which have their own private data store. Each service may perform local transactions against their data store, but distributed transactions in the classical sense are impractical in a miroservices architecture, where holding locks for the two-phase protocol would impair performance and scalability.
The Saga pattern consists of a series of steps with actions and corresponding compensating actions. Steps have a sequence number, and actions have a command which is executed by a participating microservice and has an expected result. The saga can then use the result as a basis for executing the next step or initiating a rollback with a series of compensating actions. Sagas can be configured and persisted via a durable data store.
The Saga orchestrator coordinates the entire process by telling each participant what to do and invoking the next participant in either moving the saga forward or rolling it backwards. The orchestrator can run in the same process as the initiating microservice, and it can also communicate with other microservices asynchronously through an event bus abstraction.

dotnet run.dotnet tool install -g EventDriven.Sagas.SagaConfig.CLI --version 1.0.0-beta1
sagaconfig command, passing required parameters.
-id parameter for the Saga Config Id.-p parameter.-j parameter.-uri parameter to save a config JSON file and post to the SagaConfig Service.
sagaconfig -id d89ffb1e-7481-4111-a4dd-ac5123217293 -p bin/Debug/net6.0 -j json -uri http://localhost:5256/api/sagaconfig/
Note: As an alternative to Tye, you can run services directly usng the Dapr CLI. This may be useful for troubleshooting Dapr issues after setting
Microsoft.AspNetCorelogging level toDebug.dapr run --app-id service-name --app-port #### --components-path ../dapr/components -- dotnet run
tye run
tye run --debug *
OrderCommandController.
Create method.
_commandHandler.Handle.CreateOrderSaga.
ExecuteCurrentActionAsync method.
SagaCommandDispatcher.DispatchCommandAsync.HandleCommandResultAsync methods.
HandleCommandResultForStepAsync.CustomerCreditReserveFulfilledEventHandler.
HandleAsync method.
handler.HandleCommandResultAsync.ProductInventoryReserveFulfilledEventHandler.
HandleAsync method.
handler.HandleCommandResultAsync.ProductInventoryReserveRequestedEventHandler.
HandleAsync method.
_commandHandler.Handle.CustomerCreditReserveRequestedEventHandler.
HandleAsync method.
_commandHandler.Handle.State property should be set to 2 (Created). Customer credit and product inventory should be reduced accordingly.
State property should be set to 0 (Initial) and the customer credit should be unchanged.State property may be set to 1 (Pending). If this is the case you may need to delete the order record in MongoDB, or reset the State property of the order to 0 (Initial).Saga orchestration begins with the service that initiates the saga. In the reference architecture this is the Order service. Sagas consist of steps, actions and commands, which are arranged in a saga configuration that is read from a durable store.
The first step is to create a saga orchestrator class that inherits from PersistableSaga, which ensures that snapshots of the saga are persisted as each step is executed. In the Order service this is the CreateOrderSaga class.
The following diagram illustrates how various classes are used in the execution of a saga.
In the reference-architecture/SagaConfigDefintiions project, the CreateOrderSagaConfigDefinition class implements ISagaConfigDefinition with a CreateSagaConfig that accepts a saga config id and returns a SagaConfigurationDto that has steps with actions and compensating actions, each with a saga command that is serialized to a JSON string.
In the saga orchestrator class you will override two methods: ExecuteCurrentActionAsync, for executing actions when the saga is started, and ExecuteCurrentCompensatingActionAsync, for executing compensating actions when the saga is rolled back. Each of these uses a dispatcher to execute a command that is defined in the saga configuration.
The dispatcher sends the command to a handler that uses a repository to update entity state and then publishes an integration event to the event bus. For example, the CreateOrderSagaCommandDispatcher dispatches a ReserveCustomerCredit command to the ReserveCustomerCreditCommandHandler, which publishes a CustomerCreditReserveRequest integration event to an IEventBus.
Other services, such as Customer and Inventory, subscribe to integration events and use their own command handlers to process requests and publish responses back to the event bus.
The service that initiated the saga has its own integration event handlers to handle responses published by external services. For example, the Order service has a CustomerCreditReserveFulfilledEventHandler that dispatches the result to CreateOrderSaga, which implements ISagaCommandResultHandler<CustomerCreditReserveResponse> with a HandleCommandResultAsync method that updates the saga state machine so that it knows whether to execute the next step in the saga or to roll back the saga with a series of compensating actions.
In the case of CreateOrderSaga, it is configured to perform the following steps:
Intial to Pending in order to lock the saga and prevent changes to the order while the saga is being executed.Initial.Created.For step-by-step instructions on how to build a saga orchestration that executes updates across multiple services, please see the Development Guide.