SimpleEventFlow.Core 0.1.0

dotnet add package SimpleEventFlow.Core --version 0.1.0
                    
NuGet\Install-Package SimpleEventFlow.Core -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SimpleEventFlow.Core" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SimpleEventFlow.Core" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="SimpleEventFlow.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SimpleEventFlow.Core --version 0.1.0
                    
#r "nuget: SimpleEventFlow.Core, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SimpleEventFlow.Core@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SimpleEventFlow.Core&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=SimpleEventFlow.Core&version=0.1.0
                    
Install as a Cake Tool

SimpleEventFlow

A simple implementation of the event sourcing pattern in C#.

Description

This project demonstrates the basics of event sourcing, where the state of an application is determined by a sequence of events. It includes:

  • Event: A base class for all events.
  • AggregateRoot: An abstract class for aggregate roots, which are entities that handle events and maintain state.
  • EventStore: An in-memory implementation of an event store to persist events.
  • AggregateRepository: A repository to load and save aggregates by applying events.

Features

  • Event sourcing pattern implementation.
  • In-memory event store for simplicity.
  • Easy-to-use aggregate repository for managing aggregates.

Usage

  1. Define Events: Create event classes by inheriting from Event.
  2. Define Aggregates: Create aggregate classes by inheriting from AggregateRoot. Register event handlers and raise events when state changes.
  3. Use Repository: Use AggregateRepository to load and save your aggregates.

Example

Here's a simple example of a bank account using event sourcing.

Events

public class AccountCreatedEvent : Event
{
    public decimal InitialBalance { get; init; }
}

public class DepositMadeEvent : Event
{
    public decimal Amount { get; init; }
}

public class WithdrawalMadeEvent : Event
{
    public decimal Amount { get; init; }
}

Aggregate

public class BankAccount : AggregateRoot
{
    public decimal Balance { get; private set; }

    public BankAccount()
    {
        RegisterHandler<AccountCreatedEvent>(Handle);
        RegisterHandler<DepositMadeEvent>(Handle);
        RegisterHandler<WithdrawalMadeEvent>(Handle);
    }

    private void Handle(AccountCreatedEvent evt)
    {
        Balance = evt.InitialBalance;
    }

    private void Handle(DepositMadeEvent evt)
    {
        Balance += evt.Amount;
    }

    private void Handle(WithdrawalMadeEvent evt)
    {
        Balance -= evt.Amount;
    }

    public void CreateAccount(Guid accountId, decimal initialBalance)
    {
        AggregateId = accountId;
        
        var evt = new AccountCreatedEvent
        {
            EventId = Guid.NewGuid(),
            EventType = nameof(AccountCreatedEvent),
            EventTypeVersion = 1,
            EventOccuredUtc = DateTime.UtcNow,
            AggregateId = accountId,
            AggregateVersion = this.AggregateVersion + 1,
            InitialBalance = initialBalance
        };
        RaiseEvent(evt);
    }

    public void Deposit(decimal amount)
    {
        var evt = new DepositMadeEvent
        {
            EventId = Guid.NewGuid(),
            EventType = nameof(DepositMadeEvent),
            EventTypeVersion = 1,
            EventOccuredUtc = DateTime.UtcNow,
            AggregateId = this.AggregateId ?? throw new InvalidOperationException("AggregateId not set"),
            AggregateVersion = this.AggregateVersion + 1,
            Amount = amount
        };
        RaiseEvent(evt);
    }

    public void Withdraw(decimal amount)
    {
        if (Balance < amount)
            throw new InvalidOperationException("Insufficient funds");

        var evt = new WithdrawalMadeEvent
        {
            EventId = Guid.NewGuid(),
            EventType = nameof(WithdrawalMadeEvent),
            EventTypeVersion = 1,
            EventOccuredUtc = DateTime.UtcNow,
            AggregateId = this.AggregateId ?? throw new InvalidOperationException("AggregateId not set"),
            AggregateVersion = this.AggregateVersion + 1,
            Amount = amount
        };
        RaiseEvent(evt);
    }
}

Using the Repository

var eventStore = new EventStore();
var repository = new AggregateRepository(eventStore);

var accountId = Guid.NewGuid();

// Create account
var account = new BankAccount();
account.CreateAccount(accountId, 100m);
await repository.SaveAggregateAsync(account);

// Load account and make a deposit
var loadedAccount = await repository.GetAggregateAsync<BankAccount>(accountId);
loadedAccount.Deposit(50m);
await repository.SaveAggregateAsync(loadedAccount);

// Load account and make a withdrawal
loadedAccount = await repository.GetAggregateAsync<BankAccount>(accountId);
loadedAccount.Withdraw(30m);
await repository.SaveAggregateAsync(loadedAccount);

Installation

...

Notes

  • This implementation uses an in-memory event store for simplicity. In a production environment, you would want to use a persistent event store.
  • Concurrency control and other advanced features are not implemented in this example.
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on SimpleEventFlow.Core:

Package Downloads
SimpleEventFlow.InMemory

A simple implementation of the event sourcing pattern in C#.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 152 5/4/2025