EventStoreCore 1.0.2-beta.1

This is a prerelease version of EventStoreCore.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package EventStoreCore --version 1.0.2-beta.1
                    
NuGet\Install-Package EventStoreCore -Version 1.0.2-beta.1
                    
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="EventStoreCore" Version="1.0.2-beta.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EventStoreCore" Version="1.0.2-beta.1" />
                    
Directory.Packages.props
<PackageReference Include="EventStoreCore" />
                    
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 EventStoreCore --version 1.0.2-beta.1
                    
#r "nuget: EventStoreCore, 1.0.2-beta.1"
                    
#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 EventStoreCore@1.0.2-beta.1
                    
#: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=EventStoreCore&version=1.0.2-beta.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=EventStoreCore&version=1.0.2-beta.1&prerelease
                    
Install as a Cake Tool

EventStoreCore

EventStoreCore provides event sourcing, projections, subscriptions, scheduler-backed delayed work, and a standalone EF entity outbox for .NET applications.

Install

dotnet add package EventStoreCore

Add the provider packages you need:

  • EventStoreCore.Postgres or EventStoreCore.SqlServer
  • EventStoreCore.Hangfire for Hangfire-backed delayed work
  • EventStoreCore.Quartz for Quartz-backed delayed work
  • EventStoreCore.TickerQ for TickerQ-backed delayed work

Applications own their DbContext, database connection, and EF Core migrations. Call the selected provider's UseEventStore() from OnModelCreating, then call ExistingDbContext<TDbContext>() during EventStoreCore registration. Inline appends and projections use that context and transaction. Daemon lock infrastructure remains application-owned.

Highlights

  • Inline and eventual projections
  • Subscription daemons with checkpointing
  • Stable global event-log paging across streams
  • Atomic domain-event capture from ordinary EF entities
  • Standalone outbox reader and independently checkpointed outbox subscriptions
  • Stable outbox subscription identities and recovery/replay management
  • Replay-aware scheduler integrations
  • Provider packages for common infrastructure

Behavioral guarantees

  • Stream identity consists of stream ID, stream type, and tenant ID.
  • Event versions are ordered within that complete stream identity.
  • Event IDs are generated GUIDs with a uniqueness constraint; their values are stable deduplication keys, not a source of ordering.
  • Inline projections participate in the append transaction.
  • Subscriptions and eventual projections are at-least-once and consumers must be idempotent.
  • Provider-specific storage types and migration considerations are documented by the PostgreSQL and SQL Server packages.

Bounded stream reads

Use ReadPageAsync for explicit pages or ReadAsync for cancellation-aware asynchronous enumeration. StreamReadOptions supports inclusive forward and backward version boundaries. Each page first captures the current stream version, and its event query excludes later appends. Events are ordered by stream version; ranges outside the stream are empty. A missing stream returns null from ReadPageAsync and produces an empty asynchronous sequence.

Paged reads always read persisted events and do not use aggregate snapshots. FetchForReadingAsync<TState> remains the state-rehydration API and may use a compatible snapshot. Historical typed reads only use a snapshot whose stream version is not newer than the requested historical version.

Global event-log reads

Inject the scoped IEventLogReader registered by ExistingDbContext<TDbContext>(), or use dbContext.EventLog, to read across all streams in ascending global sequence order.

var page = await eventLogReader.ReadPageAsync(new EventLogReadOptions
{
    AfterSequence = checkpoint,
    TenantId = tenantId,
    StreamTypes = ["orders"],
    EventTypes = ["order_created"],
    MaxCount = 500
}, ct);

Pages expose the highest currently visible unfiltered HeadSequence, bounded by an explicit ThroughSequence, and an exclusive NextSequence cursor. Async enumeration freezes that sequence bound automatically. Filters run in the database before paging. Event aliases, serializers, and schema upcasters are applied during materialization.

Database sequences are allocated before transaction commit. Under concurrent appends, a lower sequence can therefore become visible after a higher sequence. Live consumers should overlap reads and deduplicate by event ID instead of treating HeadSequence as a strict commit fence.

Add an application migration for the unique Events.Sequence index and the tenant, stream-type, and event-type sequence indexes when upgrading an existing database.

Event metadata

Wrap a payload with payload.WithMetadata(new EventMetadata(...)) to persist correlation ID, causation ID, actor, and application headers. Read events expose those immutable values plus the authoritative logical event type, stream type, tenant, stream version, and global sequence. Transport integrations should map reserved values to their native correlation/causation fields where available and preserve application headers without treating transport-specific concepts as Core metadata.

Existing rows remain compatible with null correlation, causation, and actor values, {} headers, and schema version 1. Migrations should add those event columns with those defaults before deploying writers that use metadata.

Propagation conventions

Core metadata remains transport-neutral. Integration code should apply these stable mappings and preserve values rather than generating new identities at each hop:

EventStoreCore CloudEvents MassTransit Durable Task input/envelope
IEvent.Id id MessageId or a dedicated source-event header source event ID used for activity/orchestration deduplication
CorrelationId correlationid extension CorrelationId application correlation ID
CausationId causationid extension InitiatorId or a dedicated causation header triggering event/message ID
Actor actor extension application header application actor field
application headers non-conflicting extension attributes application headers serialized application headers
logical event type/schema version type plus schemaversion message type plus schema-version header explicit event type and schema-version fields
stream type, tenant, stream version, global sequence extension attributes headers explicit ordering and tenant fields

Reserved transport fields must not be copied into application headers. Replay may deliver the same source event again, so downstream publishers and workflow starters should use IEvent.Id as the stable deduplication key. Correlation IDs group a business operation; they are not delivery-deduplication keys.

Serialization and schema evolution

Event and snapshot payloads use IEventStoreSerializer. Configure a replacement with UseSerializer or configure the default JSON implementation with UseSystemTextJson. A format change must remain backward-readable or be paired with explicit schema-version changes.

Register logical event names and current schema versions with AddEvent<T>("logical_name", schemaVersion, ...). Version upcasters form an explicit chain; each source version can have exactly one next step, steps run in ascending version order, and missing steps fail materialization. Snapshot registrations also have a schema version. A mismatch rebuilds from events by default, or can throw when the application wants to run an explicit snapshot migration first.

Database migrations should add Events.SchemaVersion and Snapshots.SchemaVersion as non-null integers defaulting to 1, alongside the metadata columns described above. Backfill and validate historical fixtures before removing defaults.

See the repository README for the full setup and examples:

Product 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.

NuGet packages (11)

Showing the top 5 NuGet packages that depend on EventStoreCore:

Package Downloads
EventStoreCore.MassTransit

MassTransit publisher integration for EventStoreCore stream and entity-outbox subscriptions.

EventStoreCore.Testing

Behavior-style event stream testing helpers for EventStoreCore.

EventStoreCore.Postgres

PostgreSQL EF Core persistence configuration for EventStoreCore.

EventStoreCore.CloudEvents

CloudEvents mapping for EventStoreCore stream and entity-outbox subscriptions.

EventStoreCore.EventGrid

Azure Event Grid publisher integration for EventStoreCore stream and entity-outbox subscriptions.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2-beta.2 163 7/28/2026
1.0.2-beta.1 95 7/26/2026
1.0.1 436 5/25/2026
1.0.0-beta.13 220 4/8/2026
1.0.0-beta.12 634 2/15/2026
1.0.0-beta.11 75 2/13/2026
1.0.0-beta.10 72 2/13/2026
1.0.0-beta.9 133 2/5/2026
1.0.0-beta.8 84 2/3/2026
1.0.0-beta.7 89 2/3/2026
1.0.0-beta.6 78 2/2/2026
1.0.0-beta.5 78 1/17/2026
1.0.0-beta.4 77 1/16/2026
1.0.0-beta.3 80 1/15/2026
1.0.0-beta.2 86 1/14/2026
1.0.0-beta.1 87 1/13/2026
0.9.1 131 1/12/2026
0.9.0 135 1/12/2026
0.8.1 212 12/23/2025
0.8.0-beta.3 169 12/23/2025
Loading failed