Skip to content

Persistence

trailmax edited this page Jan 22, 2017 · 3 revisions

Persistence

Persistence is used to preserve state and metadata from sagas: SagaData and Headers in every saga-class:

public class VerySimpleSaga : ISaga<DataStorage>
{
    public Guid CorrelationId { get; set; }
    public Dictionary<string, string> Headers { get; set; }
    public DataStorage SagaData { get; set; }

And CorrelationId is the key to the storage - this is how the information is retrieved.

By default NSaga comes with 2 types of persistence - In-Memory and in SQL Server. Class names are InMemorySagaRepository and SqlSagaRepository.

In-Memory Saga Repository

This is a temporary storage for a quick prototype-development and is not recommended for production.

Sql Saga Repository

Sql Repository is saving data in a database. Currently only tested against SQL Server. But the backing DB-layer for this repository is PetaPoco that can work with a range of RDBMS: SQL Server, SQL Server CE, MS Access, SQLite, MySQL, MariaDB, Firebird, and PostgreSQL, Oracle. Probbably it will be very easy to make all of these databases to get supported, but currently there is no need.

If you would like to use NSaga with something other than SQL Server, please let us know by creating an issue.

To get started with SQL Server persistence you need to configure internal container (or your own if you are not using NSaga-provided one) to resolve SqlSagaRepository. This is done like this:

var builder = Wireup.UseInternalContainer()
                    .UseSqlServer()
                    .WithConnectionStringName("MyConnectionName");

This will tell NSaga to lookup connection string name by the provided name in your app.config or web.config. Or you can provide your connection string directly:

var builder = Wireup.UseInternalContainer()
                    .UseSqlServer()
                    .WithConnectionString(@"Data Source=.\SQLEXPRESS;integrated security=SSPI;Initial Catalog=NSaga");

If you are using your own DI container, you'll need to bear in mind that SqlSagaRepository takes a dependency that was not mentioned before: IConnectionFactory. There is a default implmentation provided ConnectionFactory that creates an open connection to SQL Server - just register this with your container.

Database Schema

To create all the required tables for NSaga you need to execute install.sql - this will create separate schema called NSaga and will create 2 tables: NSaga.Sagas and NSaga.Headers. You only need to do this once for setting up.

Azure Table Persistence

You can also use Azure Tables to store your sagas. For that you'll need to install NuGet NSaga.AzureTables.

If you are using internal DI container, configuration goes like this:

using System;
using NSaga;
using NSaga.AzureTables;

// You need Azure Storage emulator running to run this
var connectionString = "UseDevelopmentStorage=true";
var builder = Wireup.UseInternalContainer()
                    .UseRepository<AzureTablesSagaRepository>()
                    .Register(typeof(ITableClientFactory), new TableClientFactory(connectionString));

If you are using your own DI container, you need to register class AzureTablesSagaRepository as ISagaRepository and class TableClientFactory as ITableClientFactory. ITableClientFactory can be registered as a singleton - the only thing it holds is a connection string.

Sample configuration for SimpleInjector should look like:

using System;
using NSaga;
using NSaga.AzureTables;
using NSaga.SimpleInjector;
using SimpleInjector;

var container = new Container();
container.RegisterNSagaComponents();
container.UseSagaRepository<AzureTablesSagaRepository>();

// You need Azure Storage emulator running to run this
var connectionString = "UseDevelopmentStorage=true";
container.Register<ITableClientFactory>(() => new TableClientFactory(connectionString), Lifestyle.Singleton);

sagaMediator = container.GetInstance<ISagaMediator>();