Koto.EventSourcing.Marten
0.4.0
There is a newer prerelease version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package Koto.EventSourcing.Marten --version 0.4.0
NuGet\Install-Package Koto.EventSourcing.Marten -Version 0.4.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="Koto.EventSourcing.Marten" Version="0.4.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Koto.EventSourcing.Marten" Version="0.4.0" />
<PackageReference Include="Koto.EventSourcing.Marten" />
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 Koto.EventSourcing.Marten --version 0.4.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Koto.EventSourcing.Marten, 0.4.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 Koto.EventSourcing.Marten@0.4.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=Koto.EventSourcing.Marten&version=0.4.0
#tool nuget:?package=Koto.EventSourcing.Marten&version=0.4.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Koto.EventSourcing.Marten
Event Sourcing on PostgreSQL via Marten. Part of the Koto suite.
Install
dotnet add package Koto.EventSourcing.Marten
What's included
| Type | Purpose |
|---|---|
EventSourcedAggregateRoot<TId> |
Base class with RaiseEvent, Apply, and Reconstitute |
IEventSourcedRepository<TAgg, TId> |
Persistence contract for event-sourced aggregates |
MartenEventSourcedRepository<TAgg, TId> |
Marten-backed implementation |
InlineProjection<TReadModel, TId> |
Base for inline single-stream projections |
AsyncProjection<TReadModel, TId> |
Base for async daemon single-stream projections |
AddKotoMarten() |
Registers Marten and the generic repository |
Usage
1 — Define an event-sourced aggregate
public sealed class Order : EventSourcedAggregateRoot<OrderId>
{
public decimal Total { get; private set; }
public bool IsShipped { get; private set; }
public static Order Place(OrderId id, decimal total)
{
var order = new Order();
order.RaiseEvent(new OrderPlaced(Guid.NewGuid(), DateTime.UtcNow, id, total));
return order;
}
public void Ship() => RaiseEvent(new OrderShipped(Guid.NewGuid(), DateTime.UtcNow));
protected override void Apply(IDomainEvent @event)
{
switch (@event)
{
case OrderPlaced e: Total = e.Total; break;
case OrderShipped: IsShipped = true; break;
}
}
private Order() { }
}
2 — Register
builder.Services.AddKotoMarten(
builder.Configuration.GetConnectionString("Db")!,
opts =>
{
// optional extra Marten config
opts.Projections.Add<OrderSummaryProjection>(ProjectionLifecycle.Async);
});
3 — Use the repository
public class PlaceOrderHandler : ICommandHandler<PlaceOrderCommand, OrderId>
{
private readonly IEventSourcedRepository<Order, OrderId> _orders;
public async Task<Result<OrderId>> HandleAsync(PlaceOrderCommand cmd, CancellationToken ct = default)
{
var order = Order.Place(OrderId.New(), cmd.Total);
await _orders.SaveAsync(order, ct);
return order.Id;
}
}
4 — Write a projection
public sealed class OrderSummaryProjection : AsyncProjection<OrderSummary, Guid>
{
public OrderSummary Create(OrderPlaced e) => new(e.OrderId, e.Total, false);
public OrderSummary Apply(OrderShipped _, OrderSummary current) =>
current with { IsShipped = true };
}
Using Marten alongside EF Core
Marten and Koto.Infrastructure.EFCore can share the same PostgreSQL instance. Marten manages event streams (mt_events, mt_streams); EF Core manages read models and other entities.
Atomic multi-stream commits
// перевод: события в двух стримах + идемпотентный маркер — одна транзакция
accounts.Append(from);
accounts.Append(to);
session.Store(new ProcessedOperation($"transfer:{operationId}"));
await unitOfWork.CommitAsync(ct); // MartenUnitOfWork, регистрируется AddKotoMarten (TryAddScoped)
SaveAsync остаётся одноагрегатным шорткатом (Append + commit). Uncommitted events агрегатов
очищаются только после успешного коммита; RollbackAsync отбрасывает всё застейдженное.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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.
-
net10.0
- Koto.Application (>= 0.4.0)
- Koto.Domain (>= 0.4.0)
- Marten (>= 8.37.0)
- OpenTelemetry.Api (>= 1.15.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.5.0-preview.1 | 48 | 11/8/2026 |
| 0.4.0 | 153 | 7/21/2026 |
| 0.3.0-preview.15 | 87 | 7/21/2026 |
| 0.3.0-preview.14 | 79 | 7/21/2026 |
| 0.3.0-preview.13 | 76 | 7/21/2026 |
| 0.3.0-preview.12 | 79 | 7/21/2026 |
| 0.3.0-preview.11 | 85 | 7/21/2026 |
| 0.3.0-preview.10 | 84 | 7/21/2026 |
| 0.3.0-preview.9 | 92 | 7/21/2026 |
| 0.3.0-preview.8 | 75 | 7/21/2026 |
| 0.3.0-preview.7 | 78 | 7/21/2026 |
| 0.3.0-preview.6 | 76 | 7/20/2026 |
| 0.3.0-preview.5 | 75 | 7/19/2026 |
| 0.3.0-preview.4 | 79 | 7/19/2026 |
| 0.3.0-preview.3 | 87 | 7/11/2026 |
| 0.3.0-preview.2 | 85 | 7/11/2026 |
| 0.3.0-preview.1 | 91 | 7/3/2026 |
| 0.2.0-preview.1 | 99 | 6/28/2026 |
| 0.1.0-preview.5 | 89 | 5/13/2026 |
| 0.1.0-preview.4 | 83 | 5/13/2026 |
Loading failed