Skip to content

Getting Started

Preview Event Sourcing Reviewed 2026-09-14 purview-dev/eventsourcing aggregates azure-cosmosdb azure-storage cqrs csharp ddd dotnet event-driven event-sourcing event-store mongodb postgresql roslyn snapshots source-generator sql-server transactions
Terminal window
dotnet add package Purview.EventSourcing

Add one or more provider packages based on your persistence target:

Terminal window
dotnet add package Purview.EventSourcing.SqlServer
dotnet add package Purview.EventSourcing.Postgres
dotnet add package Purview.EventSourcing.AzureStorage
dotnet add package Purview.EventSourcing.MongoDB
dotnet add package Purview.EventSourcing.CosmosDb

Optional packages:

Terminal window
# In-memory provider (local/test scenarios)
dotnet add package Purview.EventSourcing.InMemory
# Validation adapters
dotnet add package Purview.EventSourcing.Validation.FluentValidation
dotnet add package Purview.EventSourcing.Validation.ZodSharp

If your project references the Purview.EventSourcing.Validation.ZodSharp project directly and uses ZodSharp types, you must add:

<PackageReference Include="Purview.ZodSharp" />

Purview.EventSourcing.Validation.ZodSharp ships a build-time check (ValidateZodSharpDirectReference) in package buildTransitive assets so consumer projects fail fast with remediation guidance when this direct package reference is missing.

using Purview.EventSourcing.Aggregates;
[Aggregate]
public partial class OrderAggregate : AggregateBase
{
public string CustomerId { get; private set; } = default!;
public decimal Total { get; private set; }
[Event]
public partial void CreateOrder(string customerId);
[Event]
public partial void AddLineItem(string productId, string productName, int quantity, decimal unitPrice);
}
// SQL Server / Azure SQL (events + queryable snapshots)
builder.Services.AddSqlServerEventStore();
builder.Services.AddSqlServerSnapshotQueryableEventStore();

Other provider registrations:

// Azure Storage (event store with blob support)
builder.Services.AddAzureStorageEventStore();
// PostgreSQL (events + queryable snapshots)
builder.Services.AddPostgresEventStore();
builder.Services.AddPostgresSnapshotQueryableEventStore();
// MongoDB (events + queryable snapshots)
builder.Services.AddMongoDBEventStore();
builder.Services.AddMongoDBSnapshotQueryableEventStore();
// Cosmos DB (queryable snapshots)
builder.Services.AddCosmosDbSnapshotQueryableEventStore();
// Core-only fallback for projects without persistent query snapshots
builder.Services.AddNullQueryableEventStore();
public sealed class OrderService(IEventStore store)
{
public async Task PlaceOrderAsync(string orderId, string customerId, CancellationToken cancellationToken)
{
var order = await store.GetAsync<OrderAggregate>(orderId, cancellationToken)
?? await store.CreateAsync<OrderAggregate>(orderId, cancellationToken: cancellationToken);
order.CreateOrder(customerId);
await store.SaveAsync(order, cancellationToken);
}
}

Query aggregate event history (time/range filters)

Section titled “Query aggregate event history (time/range filters)”
var history = await store.GetEventHistoryAsync<OrderAggregate>(
aggregateId: orderId,
request: new AggregateEventHistoryRequest
{
FromVersion = 10,
ToVersion = 50,
FromUtc = DateTimeOffset.UtcNow.AddDays(-7),
MaxRecords = 100
},
cancellationToken: cancellationToken);
foreach (var item in history.Results)
{
Console.WriteLine($"{item.AggregateVersion} {item.When:u} {item.EventType}");
}

If you plan to query snapshot JSON deeply in SQL providers, read the SQL Server guide and provider matrix before relying on nested predicates through scalar value object .Value members.