Skip to content

Latest commit

 

History

History
69 lines (48 loc) · 2.96 KB

CUSTOMIZATION.md

File metadata and controls

69 lines (48 loc) · 2.96 KB

Customization

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

Serialization

About serialization you can read in SERIALIZATION file.

Create your own storage implementation

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 on StreamDatabaseBase abstract class.

  • IStreamUnitOfWork - provides methods for appending events to the stream and saving changes.
    Create your own implementation based on StreamUnitOfWorkBase 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 using System.Text.Json or any other, by implementing IEventSerializer interface.

Considerations

  • 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 by ACID compliant DBMS.

  • Get and Delete operations must be implemented as idempotent by their nature.