Complex saga finding logic

Component: NServiceBus
NuGet Package NServiceBus (5.x)
Standard support for version 5.x of NServiceBus has expired. For more information see our Support Policy.

A saga can handle multiple messages. When NServiceBus receives a message that should be handled by a saga, it uses the configured mapping information to determine the correct saga instance that should handle the incoming message. In many cases the correlation logic is simple and can be specified using the provided mapping function, which is the recommended default approach. However, if the correlation logic is very complex it might be necessary to define a custom saga finder.

Custom Saga Finders are created by implementing IFindSagas.

public class MySagaFinder :
    DbSessionProvider sessionProvider;

    // Inject the persistence specific session provider
    // For example purposes DbSessionProvider is a stub
    public MySagaFinder(DbSessionProvider sessionProvider)
        this.sessionProvider = sessionProvider;

    public MySagaData FindBy(MyMessage message)
        // Use the injected sessionProvider to get a db session
        // For example GetDbSession is a stub extension method
        var dbSession = sessionProvider.GetDbSession();
        return dbSession.GetSagaFromDB(message.SomeId, message.SomeData);
        // If a saga can't be found null should be returned
In NServiceBus Versions 6 and above, and all integrations that target those versions, all extension points that return Task cannot return a null Task. These APIs must return an instance of a Task, i.e. a pending Task or a CompletedTask, or be marked async. For extension points that return a Task<T>, return the value directly (for async methods) or wrap the value in a Task.FromResult(value).

Many finders may exist for a given saga or message type. If a saga can't be found and if the saga specifies that it is to be started for that message type, NServiceBus will know that a new saga instance is to be created.

When using custom saga finders, users are expected to configure any additional indexes needed to handle concurrent access to saga instances properly using the tooling of the selected storage engine. Due to this constraint, persisters are not all able to support custom saga finders to the same degree.

In instances where saga correlation requires data from more than one property on an incoming message, a better alternative is to use a message property expression instead of the overhead of a custom saga finder.


Related Articles

  • Saga concurrency
    NServiceBus ensures consistency between saga state and messaging.
  • Sagas
    NServiceBus uses event-driven architecture to include fault-tolerance and scalability in long-term business processes.

Last modified