NServiceBus
NServiceBus copied to clipboard
Persistence: Synchronized storage adapter removal
The synchronized storage session adapter has been removed and the persistence seam simplified to enable first-class dependency injection support for the storage session. Persisters can simply register the concrete storage session and the rest of the mechanics will be taken care by Core automatically.
Feature Dependencies
- Make sure the outbox and saga features have a dependency to the storage specific synchronized storage feature
- Make sure the storage specific synchronized storage feature has a dependency on the core SynchronizedStorage feature
Example from SQL Persistence:
class SqlSagaFeature : Feature
{
SqlSagaFeature()
{
Defaults(s =>
{
s.EnableFeatureByDefault<SqlStorageSessionFeature>();
});
DependsOn<Sagas>();
DependsOn<SqlStorageSessionFeature>();
}
}
class SqlStorageSessionFeature : Feature
{
public SqlStorageSessionFeature()
{
DependsOn<SynchronizedStorage>();
}
}
ICompletableSynchronizedStorageSession
- Implement the new methods on the
ICompletableSynchronizedStorageSessioninterface - Move the implementations of
ISynchronizedStorage.OpenSessionintoICompletableSynchronizedStorageSession.OpenSession - Move the implementations of
ISynchronizedStorageAdapter.TryAdaptinto the correspondingTryOpenmethods ofICompletableSynchronizedStorageSession
Depending on the needs of the persistence it might make sense to split the completable synchronized storage implementation into two independent session concept. One session concept representing the needs of the core and one session object representing the session state that is shared between the outbox and the completable storage session similar to the spike in CosmosDB.
DI Registration
In the storage session feature make sure to:
- Register a scoped implementation of
ICompletableSynchronizedStorageSessionto the concrete storage session - Add a scoped implementation that maps the persistence specific synchronized storage session implementation to
provider.GetService<ISynchronizedStorageSession>().PersistenceSpecificExtension()
Example from SQL Persistence:
class SqlStorageSessionFeature : Feature
{
protected override void Setup(FeatureConfigurationContext context)
{
services.AddScoped<ICompletableSynchronizedStorageSession>(provider => new StorageSession(connectionManager, provider.GetService<SagaInfoCache>(), sqlDialect));
services.AddScoped(provider => provider.GetService<ISynchronizedStorageSession>().SqlPersistenceSession());
}
}
Persistence Tests
Delete on the PersistenceTestConfiguration partial class the no longer required properties:
public ISynchronizedStorage SynchronizedStorage { get; private set; }
public ISynchronizedStorageAdapter SynchronizedStorageAdapter { get; private set; }
implement the CreateStorageSession factory delegate to return a new StorageSession object every time it is called. Example:
public Func<ICompletableSynchronizedStorageSession> CreateStorageSession { get; private set; }
CreateStorageSession = () => new StorageSession(connectionManager, infoCache, dialect);
Custom pipeline state holder infrastructure
Delete existing behaviors, associated class and DI registrations that managed storage session context for the incoming pipeline. That part is no longer needed since the scope is now managed by the core.