Skip to content

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

StreamDingo Logo

StreamDingo

A high-performance .NET library for event sourcing with hash-based integrity verification and snapshot-based replay

Build Status Code Coverage Security Advisories .NET Version License

✨ Features

  • Event Sourcing Made Simple: Clean, intuitive API for implementing event sourcing patterns
  • Hash-Based Integrity: Built-in integrity verification using cryptographic hashes for events, handlers, and snapshots
  • Snapshot-Based Replay: Efficient event replay from snapshots with intelligent invalidation
  • Code Change Detection: Automatic detection of event handler changes with smart replay strategies
  • High Performance: Optimized for throughput with minimal memory allocation
  • Type Safety: Strongly typed event handlers and snapshots with full generic support
  • Framework Integration: Seamless integration with ASP.NET Core, dependency injection, and logging

πŸš€ Quick Start

Installation

Install StreamDingo via NuGet Package Manager:

dotnet add package StreamDingo

Or via Package Manager Console:

Install-Package StreamDingo

Basic Usage

using StreamDingo;

// Define your events
public record UserCreated(string Name, string Email);
public record UserEmailUpdated(string NewEmail);

// Define your aggregate state
public record UserState(string Name, string Email, bool IsActive = true);

// Create event handlers
public class UserEventHandlers
{
    public static UserState Apply(UserState? state, UserCreated @event)
    {
        return new UserState(@event.Name, @event.Email);
    }

    public static UserState Apply(UserState state, UserEmailUpdated @event)
    {
        return state with { Email = @event.NewEmail };
    }
}

// Use the event store
var eventStore = new StreamDingoEventStore();

// Create a new stream
var streamId = Guid.NewGuid();
await eventStore.AppendAsync(streamId, new UserCreated("John Doe", "john@example.com"));
await eventStore.AppendAsync(streamId, new UserEmailUpdated("john.doe@example.com"));

// Replay events to get current state
var currentState = await eventStore.ReplayAsync<UserState>(streamId);
Console.WriteLine($"User: {currentState.Name}, Email: {currentState.Email}");

πŸ—οΈ Core Concepts

Event Handlers

Event handlers are pure functions that take a previous state snapshot and an event, returning a new state:

public static TState Apply(TState previousState, TEvent @event)
{
    // Apply event logic
    return newState;
}

Each event handler is automatically hashed using the HashStamp library to detect code changes.

Snapshots

Snapshots represent the state of an aggregate at a specific point in time:

  • Each snapshot is cryptographically hashed for integrity verification
  • Snapshots serve as checkpoints for efficient event replay
  • The last snapshot represents the current entity state

Hash-Based Integrity

StreamDingo ensures data integrity through multiple hash layers:

  • Event Handler Hashes: Detect when business logic changes
  • Snapshot Hashes: Verify snapshot integrity and detect corruption
  • Event Hashes: Ensure event data hasn't been tampered with

Smart Replay Strategies

When changes are detected, StreamDingo intelligently replays events:

  • Event Order Changes: Replay from the last stable snapshot
  • Handler Code Changes: Replay affected event types until snapshot hashes stabilize
  • Corruption Detection: Validate integrity at each step during replay

πŸ“– API Reference

StreamDingoEventStore

The main entry point for event sourcing operations.

Methods

// Append events to a stream
Task AppendAsync<T>(Guid streamId, T @event, CancellationToken cancellationToken = default);

// Replay events to rebuild state
Task<TState> ReplayAsync<TState>(Guid streamId, CancellationToken cancellationToken = default);

// Get stream information
Task<StreamInfo> GetStreamInfoAsync(Guid streamId, CancellationToken cancellationToken = default);

// Create snapshots manually
Task CreateSnapshotAsync<TState>(Guid streamId, TState state, CancellationToken cancellationToken = default);

Configuration

Configure StreamDingo in your application:

// Program.cs
builder.Services.AddStreamDingo(options =>
{
    options.UseInMemoryStorage(); // or UseSqlServer, UsePostgreSQL, etc.
    options.EnableAutomaticSnapshots(every: 100); // Create snapshots every 100 events
    options.EnableIntegrityChecking(true);
    options.ConfigureHashing(hash => hash.IncludeMethodBodies = true);
});

πŸ”§ Development

Prerequisites

Building

Clone the repository and build:

git clone https://github.com/alexwiese/StreamDingo.git
cd StreamDingo
dotnet build

Running Tests

dotnet test

Code Formatting

We use EditorConfig for consistent code formatting:

dotnet format

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Quick Contribution Steps

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and add tests
  4. Ensure all tests pass: dotnet test
  5. Format your code: dotnet format
  6. Commit your changes: git commit -m 'Add amazing feature'
  7. Push to your fork: git push origin feature/amazing-feature
  8. Open a Pull Request

πŸ“‹ Roadmap

  • Additional storage providers (Redis, MongoDB, Event Store DB)
  • GraphQL integration
  • Event versioning and migration tools
  • Performance benchmarking suite
  • Event sourcing best practices documentation
  • Integration with popular CQRS frameworks

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Built with HashStamp for code hashing capabilities
  • Inspired by event sourcing patterns from the DDD community
  • Thanks to all contributors

πŸ“ž Support

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages