Bsft.EventAggregator.Saga 2.2.0

dotnet add package Bsft.EventAggregator.Saga --version 2.2.0
                    
NuGet\Install-Package Bsft.EventAggregator.Saga -Version 2.2.0
                    
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="Bsft.EventAggregator.Saga" Version="2.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Bsft.EventAggregator.Saga" Version="2.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Bsft.EventAggregator.Saga" />
                    
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 Bsft.EventAggregator.Saga --version 2.2.0
                    
#r "nuget: Bsft.EventAggregator.Saga, 2.2.0"
                    
#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 Bsft.EventAggregator.Saga@2.2.0
                    
#: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=Bsft.EventAggregator.Saga&version=2.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Bsft.EventAggregator.Saga&version=2.2.0
                    
Install as a Cake Tool

Bsft.EventAggregator.Saga

The saga engine of the Bsft.EventAggregator family: a fluent flow definition, a step guard that lets exactly one publisher advance a waiting step, durable timeouts on a business calendar, and one commit path that makes a step's state advance and its reminders durable together or not at all.

Install

dotnet add package Bsft.EventAggregator.Saga

Requires Bsft.EventAggregator (the transport a saga subscribes to and publishes on), Bsft.Calendar (which turns a business-time delay into a due date), Bsft.Instrumentation (which advertises the Bsft.Saga instrumentation source) and Bsft.Data.Contracts (whose PagedRequest and PagedResult are the paging vocabulary the reading seams speak). Nothing here touches ASP.NET Core, so the engine runs unchanged in a worker or a console tool. Persistence and correlation are separate packages: Bsft.EventAggregator.Saga.EFCore and Bsft.EventAggregator.Saga.Correlation.

Register

services.AddBsftEventAggregator();
services.AddBsftSaga(options =>
{
    options.Timeouts.PollInterval = TimeSpan.FromSeconds(1);
    options.Timeouts.CatchUpPolicy = SagaTimeoutCatchUpPolicy.FireLatestPerSaga;
});

// or bound from configuration, section "Bsft:Saga"
services.AddBsftSaga(configuration);

services.AddBsftSagaFlow<OrderFulfillmentFlow>();

AddBsftEventAggregator is not optional: the engine subscribes to that aggregator and registers none of its own. Every flow is registered with AddBsftSagaFlow<T>, and the host calls app.Services.UseBsftSagaFlows() once at startup — that is what configures the flows and subscribes them to their trigger events; without it no saga ever starts. The in-memory saga and timeout stores are registered with TryAdd, so they are the default only until a persistence package or the application registers its own.

Configure

Option Default Effect
BsftSagaOptions.ShouldCreateScopePerStep false Retained for source compatibility and no longer changes anything. Both ways into a step always create a scope, because a step resolves scoped services and the root provider cannot serve them.
BsftSagaOptions.Timeouts.PollInterval 00:00:05 How long the dispatcher waits after a pass that found nothing due.
BsftSagaOptions.Timeouts.BatchSize 100 The largest number of due timeouts read per pass.
BsftSagaOptions.Timeouts.CatchUpPolicy FireAll What happens to timers that came due while the application was down: fire all of them, fire only the newest per saga instance, or skip the ones older than MaxCatchUpAge.
BsftSagaOptions.Timeouts.MaxCatchUpAge 1.00:00:00 How overdue a timer may be before SkipBeyondMaxAge discards it. Ignored by the other two policies.
BsftSagaOptions.Timeouts.MaxDispatchAttempts 10 How often a timer may fail to fire before it is retired to the dead-letter state. Without a limit one timer that can never fire keeps its place at the head of every poll and eventually stops every saga timer in the application.

Validation: ValidateOnStart() rejects a negative PollInterval or MaxCatchUpAge, a BatchSize or MaxDispatchAttempts below one, and a CatchUpPolicy that is not a defined value — all of them reported in one message rather than one restart at a time. The dispatcher keeps the same guards on its own constructor arguments, because it can be constructed directly; neither is stricter than the other.

Extend

ISagaStore persists and loads a saga instance by type and correlation key; the shipped InMemorySagaStore keeps them in a dictionary and loses them with the process. ISagaTimeoutStore does the same for durable timers and owns the whole "confirm, publish, claim" sequence, so that an implementation is free to choose how it makes the claim atomic; InMemorySagaTimeoutStore is the in-process default. Both are what Bsft.EventAggregator.Saga.EFCore replaces.

ISagaInstanceReader and ISagaTimeoutReader are the listing seams: what an operator needs to answer "which sagas are stuck" and "which timers are overdue", which the stores deliberately cannot answer because they are keyed for lookup rather than for search. They are left unimplemented here for the same reason the stores' durable halves are, and Bsft.EventAggregator.Saga.EFCore implements them.

ISagaPersistenceWindow decides whether a step's state advance and its timer writes commit as one unit. The default ImmediateSagaPersistenceWindow commits nothing, which is correct for stores that already make every write durable on its own; a provider that can commit both together registers its own.

ISagaCorrelationInitializer and ISagaCorrelationAccessor are declared here and deliberately left unimplemented: the engine has no notion of correlation of its own, and a step keeps the fresh id of its own scope until a host registers a bridge. Bsft.EventAggregator.Saga.Correlation is that bridge. ISagaCorrelationScope carries the id of a firing timeout through the publish and has a working default. ISagaTimeoutPublisher resolves the persisted payload type and publishes the carried event; replace it to control deserialization. ISagaTimeoutDrainer is not a seam to replace but the supported way to run one dispatch pass on demand — the way a test models a process spanning weeks without waiting on a wall clock.

Documentation

Topic page: docs/saga.md. Conventions: docs/package-conventions.md.

Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Bsft.EventAggregator.Saga:

Package Downloads
Bsft.Testing

BSFT Framework test harnesses and test doubles for integration, mediator, and saga tests

Bsft.EventAggregator.Saga.Correlation

BSFT Framework adapter that carries the Bsft.Correlation id through durable saga timeouts

Bsft.EventAggregator.Saga.EFCore

BSFT Framework EF Core persistence for the saga engine

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.2.0 98 10/23/2026
2.1.0 166 9/28/2026