Storage
Storage is a persistence layer for the StreamStore library.
Create your own storage implementation
Implement your own storage from scratch
To create your own storage implementation, you need to implement the following interfaces:
Single tenant mode
- [IStreamStorage] - provides methods for working with streams.
- [ISchemaProvisioner] - provides methods for provisioning storage schema.
Multitenant mode
- [ITenantStreamStorageProvider] interface, provider of IStreamStorage for particular tenant.
- [ITenantSchemaProvisionerFactory] interface, factory of ISchemaProvisioner for particular tenant.
However, there is much easier way to do so.
Use base implementations
You can use base implementations of the interfaces provided by StreamStore.Storage
package.
For to do so, you need to create implementation of the following abstract classes:
-
[StorageConfiguratorBase] - provides methods for configuring storage and registering it in DI container.
Example: SQLite storage configurator
```csharp // Example of SQLite storage configurator internal class StorageConfigurator: StorageConfiguratorBase { readonly SqlStorageConfiguration config = SqliteConfiguration.DefaultConfiguration; public StorageConfigurator() { } public StorageConfigurator(SqlStorageConfiguration configuration) { config = configuration.ThrowIfNull(nameof(configuration)); } protected override void ConfigureStorage(StorageDependencyRegistrator registrator) { registrator.RegisterStorage(); } protected override void ConfigureSchemaProvisioner(SchemaProvisionerRegistrator registrator) { // Register the PostgreSQL schema provisioner registrator.RegisterSchemaProvisioner (); } protected override void ConfigureAdditionalDependencies(IServiceCollection services) { services.AddSingleton(config); services.AddSingleton<IDbConnectionFactory, SqliteDbConnectionFactory>(); services.AddSingleton<IDapperCommandFactory, DefaultDapperCommandFactory>(); services.AddSingleton<ISqlExceptionHandler, SqliteExceptionHandler>(); services.AddSingleton<ISqlQueryProvider, DefaultSqlQueryProvider>(); services.AddSingleton<IMigrator, SqliteMigrator>(); services.AddSingleton(new MigrationConfiguration { MigrationAssembly = typeof(SqliteMigrator).Assembly }); } } ``` </details> -
[MultitenancyConfiguratorBase] - provides methods for configuring multitenant aspect of storage and registering it in DI container.
Example: SQLite multitenancy configurator
```csharp internal class MultitenancyConfigurator : MultitenancyConfiguratorBase { readonly Actionconfigure; public MultitenancyConfigurator(Action configure) { this.configure = configure.ThrowIfNull(nameof(configure)); } protected override void ConfigureStorageProvider(StorageProviderRegistrator registrator) { registrator.RegisterStorageProvider(serviceProvider => serviceProvider.GetRequiredService ().GetStorage); } protected override void ConfigureSchemaProvisionerFactory(SchemaProvisionerFactoryRegistrator registrator) { registrator.RegisterSchemaProvisioningFactory(provider => provider.GetRequiredService ().Create); } protected override void ConfigureAdditionalDependencies(IServiceCollection services) { services.ThrowIfNull(nameof(services)); services.AddSingleton<ISqlTenantStorageConfigurationProvider,SqlTenantStorageConfigurationProvider>(); services.AddSingleton (); configure(new SqlMultitenancyConfigurator(services)); services.AddSingleton (); } } ``` </details>
After that you can register your storage implementation in the DI container by creating extension method for IServiceCollection
and using existing extensions.