SagaR 0.1.2

dotnet add package SagaR --version 0.1.2
                    
NuGet\Install-Package SagaR -Version 0.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SagaR" Version="0.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SagaR" Version="0.1.2" />
                    
Directory.Packages.props
<PackageReference Include="SagaR" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SagaR --version 0.1.2
                    
#r "nuget: SagaR, 0.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SagaR@0.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SagaR&version=0.1.2
                    
Install as a Cake Addin
#tool nuget:?package=SagaR&version=0.1.2
                    
Install as a Cake Tool

SagaR

CI/CD Status GitHub release

NuGet Package:

NuGet

SagaR is a lightweight, decoupled .NET library for orchestrating complex processes based on the Saga pattern. It provides a fluent API and native integration with Dependency Injection to allow you to declaratively define the sequence of operations and their corresponding compensation logic.

SagaR is designed to be agnostic of the state management framework, but it can be used in perfect synergy with libraries like TransactR to add a robust rollback mechanism to your sagas.

Key Concepts

  • Saga Pattern: Manages distributed transactions by executing a sequence of local transactions. If a transaction fails, the saga executes a series of compensating transactions to undo the preceding changes.

  • Declarative Definition: Sagas are defined cleanly and centrally during the Dependency Injection setup, keeping the business logic in handlers lean and focused.

  • Dependency Injection-first: Saga steps are resolved from the DI container, which means they can have their own dependencies (services, repositories, etc.) automatically injected.

  • Orchestration: The ISagaOrchestrator service is responsible for executing the steps in sequence and invoking compensation actions in reverse order in case of failure.

Installation

Install the NuGet package into your application.

dotnet add package SagaR.Core

Usage Example

1. Define the Steps

Each step is a class that implements ISagaStep<TContext> and contains the execution and compensation logic.

public class ReserveInventoryStep : ISagaStep<OrderContext>
{
    private readonly IInventoryService _inventory;
    public ReserveInventoryStep(IInventoryService inventory) => _inventory = inventory;
    
    public Task ExecuteAsync(OrderContext context) => _inventory.ReserveItemAsync(context.State.ItemId);
    public Task CompensateAsync(OrderContext context) => _inventory.ReleaseItemAsync(context.State.ItemId);
}

public class ProcessPaymentStep : ISagaStep<OrderContext>
{
    private readonly IPaymentService _payment;
    public ProcessPaymentStep(IPaymentService payment) => _payment = payment;

    public Task ExecuteAsync(OrderContext context) => _payment.ProcessPaymentAsync(context.State.Amount);
    public Task CompensateAsync(OrderContext context) => _payment.RefundPaymentAsync(context.State.Amount);
}

2. Define the Saga

Create a class that inherits from Saga<TContext> and receives the steps via its constructor.

public class OrderCreationSaga : Saga<OrderContext>
{
    // The DI container will inject all registered ISagaStep<OrderContext> for this saga.
    public OrderCreationSaga(IEnumerable<ISagaStep<OrderContext>> steps) : base(steps) { }
}

3. Configuration (Dependency Injection)

Use the fluent UseSagas API to register and define your saga.

// Program.cs
services.UseSagas(sagas =>
{
    sagas.MapSaga<OrderContext, OrderCreationSaga>()
         .WithStep<ReserveInventoryStep>()  // Registers the step and associates it with the saga
         .WithStep<ProcessPaymentStep>();
});

4. Saga Execution

Inject ISaga<TContext> and ISagaOrchestrator<TContext> into your handler or service to execute the saga.

public class CreateOrderHandler
{
    private readonly ISaga<OrderContext> _saga;
    private readonly ISagaOrchestrator<OrderContext> _orchestrator;
    private readonly MyContextProvider _contextProvider; // e.g., ITransactionContextProvider from TransactR

    public CreateOrderHandler(
        ISaga<OrderContext> saga, 
        ISagaOrchestrator<OrderContext> orchestrator,
        MyContextProvider contextProvider)
    {
        _saga = saga;
        _orchestrator = orchestrator;
        _contextProvider = contextProvider;
    }

    public async Task Handle(CreateOrderCommand command)
    {
        var context = _contextProvider.Context;
        // Initialize the context with data from the command...

        await _orchestrator.RunAsync(_saga, context);
    }
}

Integration with TransactR

SagaR and TransactR are designed to work together. You can use a TransactionContext from TransactR as the TContext for your saga. This way, if any saga step throws an exception, the TransactionalBehavior from TransactR will catch it and apply the rollback policy to the entire transaction state.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.2 125 9/1/2025