EventSourcingDotNet 0.27.0
See the version list below for details.
dotnet add package EventSourcingDotNet --version 0.27.0
NuGet\Install-Package EventSourcingDotNet -Version 0.27.0
<PackageReference Include="EventSourcingDotNet" Version="0.27.0" />
<PackageVersion Include="EventSourcingDotNet" Version="0.27.0" />
<PackageReference Include="EventSourcingDotNet" />
paket add EventSourcingDotNet --version 0.27.0
#r "nuget: EventSourcingDotNet, 0.27.0"
#:package EventSourcingDotNet@0.27.0
#addin nuget:?package=EventSourcingDotNet&version=0.27.0
#tool nuget:?package=EventSourcingDotNet&version=0.27.0
EventSourcingDotNet
Event Sourcing made easy
Event Store Providers
- In-Memory
- Event Store DB (experimental)
Snapshot Providers
- In-Memory
Getting Started
Define your aggregate state and ID
Aggregate ID
Create a readonly ID record struct for each of your aggregates.
It must implement the IAggregateId
interface to be accepted as an aggregate ID.
The static AggregateName
property and the AsString()
method are used to compose the stream name. You should not use dashes in your AggregateName
because some providers, e.g. Event Store DB, will split the stream name at the first dash to provide a by-category stream.
public readonly record struct MyAggregateId(Guid Id) : IAggregateId
{
public static string AggregateName => "myAggregate";
public string AsString() => Id.ToString();
}
Aggregate State
Create a state record representing the current state of your aggregate.
It must implement the generic IAggregateState<TAggregatId>
interface to be accepted as an aggregate state.
The generic type argument TAggregateId
is the aggregate ID specified above.
public sealed record MyAggregate : IAggregateState<MyAggregateId>
{
public int MyValue { get; init; }
}
Aggregate State Rules
The state record should be immutable.
Some storage or snapshot providers, e.g. the In-Memory snapshot provider, may keep a reference to the latest version of the aggregate. Mutations of the aggregate state may lead to an inconsistent aggregate state.The state record must provide a public parameterless constructor.
To create a new instance of the
Define your events
Create a record for each and every event happening on your aggregate.
An event must implement the IDomainEvent<TAggregateId, TState>
interface to be accepted as a valid event.
Each event must implement the Apply(TState)
method to update the aggregate state.
public sealed record SomethingHappened : IDomainEvent<SomeState>
{
public Something Apply(SomeState state)
{
// return updated state here
}
}
Event validation
The IDomainEvent<TAggregateId, TState>
interface provides an additional Validate
method allowing to implement logic whether an event should be fired, skipped or raise an error.
The validation happens before the event is applied to the aggregate state and added to the uncommitted events.
public sealed record SomethingHappened : IDomainEvent<SomeState>
{
// Apply method removed for brevity
public EventValidationResult Validate(SomeState state)
{
// do some validation logic here...
return EventValidationResult.Fire;
}
}
You can return the following validation results:
EventValidationResult.Fire
The event will be applied to the aggregate state and added to the uncommitted events collection.EventValidationResult.Skip
The event will be skipped. It will not be applied to the aggregate state and not added to the uncommitted events collection.
Use this validation result when the aggregate state will not be affected by the event and you want to avoid extra effect-less events in the event streamEventValidationResult.Fail(Exception)
The event cannot be applied in the current state of the aggregate or it would lead to an inconsistent state.
The method takes an Exception parameter which expresses why this event cannot be applied.
Define update logic
Aggregates are updated by getting the current version from the aggregate repository, adding some new events and then saving the aggregate back to the event store.
Avoid to run long running tasks after getting the aggregate from the repository and storing it back as it increases the risk of running into a concurrency issue.
All Event Store providers use optimistic concurrency checks to avoid update conflicts.
private readonly IAggregateRepository<SomeId, SomeState> _repository;
public async Task DoSomething(SomeRequest request)
{
var aggregate = await _repository.GetByIdAsync(request.Id);
aggregate = aggregate.AddEvent(new SomethingHappened());
await _repository.SaveAsync(aggregate);
}
Alternatively there is a shorthand extension method allowing to retrieve, update and save the aggregate in one statement:
IAggregateRepository<TAggregateId, TState>.UpdateAsync(TAggregateId aggregateId, params IDomainEvent<TState>[] events);
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. 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. |
-
net7.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- System.Linq.Async (>= 6.0.1)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on EventSourcingDotNet:
Package | Downloads |
---|---|
EventSourcingDotNet.InMemory
In-Memory provider for EventSourcingDotNet |
|
EventSourcingDotNet.EventStore
EventStoreDB provider for EventSourcingDotNet |
|
EventSourcingDotNet.Serialization.Json
JSON Serialization implementation for EventSourcingDotNet |
|
EventSourcingDotNet.FileStorage
Package Description |
|
EventSourcingDotNet.KurrentDB
KurrentDB provider for EventSourcingDotNet |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.3.0-pre.0.1 | 84 | 8/21/2025 |
1.2.3-pre.0.2 | 10 | 8/25/2025 |
1.2.3-pre.0.1 | 12 | 8/25/2025 |
1.2.2 | 15 | 8/25/2025 |
1.2.2-pre.0.2 | 65 | 8/22/2025 |
1.2.2-pre.0.1 | 89 | 8/21/2025 |
1.2.1 | 88 | 8/21/2025 |
1.2.0 | 89 | 8/21/2025 |
1.2.0-pre.0.8 | 85 | 8/21/2025 |
1.2.0-pre.0.1 | 441 | 7/21/2025 |
1.1.0 | 149 | 7/16/2025 |
1.1.0-pre.0.1 | 117 | 7/16/2025 |
1.1.0-pre.0 | 113 | 7/16/2025 |
1.0.0 | 136 | 7/16/2025 |
1.0.0-rc1.17 | 85 | 7/11/2025 |
1.0.0-rc1.16 | 86 | 7/11/2025 |
1.0.0-rc1.15 | 128 | 5/25/2025 |
1.0.0-rc1.14 | 128 | 5/25/2025 |
1.0.0-rc1.6 | 134 | 8/12/2023 |
1.0.0-rc1.5 | 123 | 8/12/2023 |
1.0.0-rc1 | 281 | 4/4/2023 |
0.31.0-pre.0.43 | 150 | 4/4/2023 |
0.31.0-pre.0.40 | 154 | 4/2/2023 |
0.31.0-pre.0.39 | 142 | 3/30/2023 |
0.31.0-pre.0.37 | 147 | 3/30/2023 |
0.31.0-pre.0.35 | 158 | 3/28/2023 |
0.31.0-pre.0.33 | 157 | 3/28/2023 |
0.31.0-pre.0.23 | 160 | 3/28/2023 |
0.31.0-pre.0.22 | 154 | 3/5/2023 |
0.31.0-pre.0.20 | 159 | 3/4/2023 |
0.31.0-pre.0.17 | 151 | 3/4/2023 |
0.31.0-pre.0.15 | 227 | 2/16/2023 |
0.31.0-pre.0.13 | 145 | 2/16/2023 |
0.31.0-pre.0.10 | 157 | 2/15/2023 |
0.31.0-pre.0.7 | 159 | 2/15/2023 |
0.31.0-pre.0.6 | 175 | 1/30/2023 |
0.31.0-pre.0.5 | 179 | 1/4/2023 |
0.31.0-pre.0.4 | 165 | 1/4/2023 |
0.31.0-pre.0.3 | 167 | 1/4/2023 |
0.31.0-pre.0.1 | 171 | 1/4/2023 |
0.30.1 | 573 | 1/4/2023 |
0.30.0 | 427 | 12/30/2022 |
0.30.0-pre.0.12 | 161 | 12/30/2022 |
0.30.0-pre.0.9 | 160 | 12/13/2022 |
0.30.0-pre.0.8 | 166 | 12/11/2022 |
0.30.0-pre.0.2 | 157 | 12/9/2022 |
0.29.1-pre.0.1 | 154 | 12/9/2022 |
0.29.0 | 431 | 12/8/2022 |
0.29.0-pre.0.52 | 155 | 12/8/2022 |
0.29.0-pre.0.51 | 154 | 12/8/2022 |
0.29.0-pre.0.43 | 159 | 12/4/2022 |
0.29.0-pre.0.42 | 159 | 12/4/2022 |
0.29.0-pre.0.41 | 164 | 11/27/2022 |
0.29.0-pre.0 | 159 | 11/24/2022 |
0.28.0 | 443 | 11/22/2022 |
0.27.0 | 434 | 11/20/2022 |
0.26.0 | 461 | 11/20/2022 |
0.25.0 | 526 | 11/20/2022 |