To implement your own database you do not need StreamStore package, all necessary interfaces are located in StreamStore.Contracts package from command line:
dotnet add package StreamStore.Contracts
or from NuGet Package Manager Console:
Install-Package StreamStore.Contracts
About serialization you can read in SERIALIZATION file.
To create your own database implementation, you need to implement the following interfaces:
-
IStreamDatabase
- provides methods for working with streams. Create your own implementation based onStreamDatabaseBase
abstract class. -
IStreamUnitOfWork
- provides methods for appending events to the stream and saving changes.
Create your own implementation based onStreamUnitOfWorkBase
and override following methods:class MyStreamUnitOfWork: StreamUnitOfWorkBase { protected override Task SaveChangesAsync(EventRecordCollection uncommited, CancellationToken token) { // Implement saving logic } protected override Task OnEventAdded(EventRecord @event, CancellationToken token) { // Optionally implement logic for handling event added, // such as instance logging, puting event to outbox or temporary storage etc. } protected override void Dispose(bool disposing) { // Optionally implement disposing logic } }
Default serializer is using
Newtonsoft.Json
library, so you can create your own usingSystem.Text.Json
or any other, by implementingIEventSerializer
interface.
-
To implement your own database you do not need StreamStore package, all necessary interfaces are located in StreamStore.Contracts package.
-
You can register your own database implementation in the DI container using any kind of lifetime (i.e. Singleton, Transient, Scoped, etc.)
However, if you register it as a singleton, you should be aware that it should be thread-safe and preferably stateless.
-
Solution already provides optimistic concurrency and event duplication control mechanisms, as a pre-check during stream opening.
However, if you need consistency guaranteed, you should implement your own mechanisms as a part of IStreamUnitOfWork implementation.
For instance, you can use a transaction mechanism supported byACID compliant DBMS
. -
Get and Delete operations must be implemented as idempotent by their nature.