# EventSourcing.NetCore teaches event sourcing through a dozen samples that split between Marten and EventStoreDB

> oskardudycz/EventSourcing.NetCore is a CC-BY-SA-4.0 learning repository: a long README, videos, two self-paced training kits and sample applications in C#. It is a curriculum with working code, and it is not an installable framework.

**oskardudycz/EventSourcing.NetCore** — Examples and Tutorials of Event Sourcing in .NET

- Repository: https://github.com/oskardudycz/EventSourcing.NetCore
- Website: https://event-driven.io
- Stars: 3,685 · Forks: 546
- Language: C#
- License: CC-BY-SA-4.0
- Published: 2026-10-08 · Updated: 2026-10-30 · Language: en
- Canonical page: https://hysenlabs.com/projects/oskardudycz-eventsourcing-netcore

## Events are stored as facts in the past tense, and the repository holds that rule

The README opens with the definition the whole repository builds on: Event Sourcing stores the results of business operations as a series of events, instead of keeping only the latest version of an entity's state. Each state change becomes its own event, so no business data is lost, and the stored history supports auditing, diagnostics, business analysis and reporting.

The naming rule is concrete. Events represent facts in the past and should be named in the past tense, such as user added or order confirmed. They are immutable, they can be ignored but not retracted, and they are broadcast rather than addressed to a recipient. The README compares this to telling a story at a party, where you hope someone listens but may find no one is paying attention.

This is a teaching repository by Oskar Dudycz, and the first section links to his articles on team autonomy, on when not to use Event Sourcing, and on the difference between a command and an event. Two sibling repositories cover JVM and NodeJS.

## Twelve numbered samples pair a domain with one of two event stores

Section 6 of the README numbers the samples, and the Sample folder holds more directories than that list. The numbered ones are Pragmatic Event Sourcing with Marten, ECommerce with Marten, Simple EventSourcing with EventStoreDB, Implementing Distributed Processes, ECommerce with EventStoreDB, Warehouse, Warehouse Minimal API, Event Versioning, Event Pipelines, Meetings Management with Marten, Cinema Tickets Reservations with Marten and SmartHome IoT with Marten.

The folder listing adds others that have no number in the table of contents: AsyncProjections, CRUDToCQRS, ClosingTheBooks, ECommerce.Equinox, Helpdesk, Helpdesk.Wolverine, HotelManagement, MartenMeetsElastic, ProjectManagement, SlimDownYourAggregate, Tickets and decider. The result is that a reader picks a domain, such as ecommerce, and can find it built twice on different stores. The ECommerce.Equinox name points to a third approach in that same domain.

## Shared Core projects wrap each backing technology separately

Beside Sample, the repository root contains reusable projects: Core, Core.Serialization, Core.Marten, Core.EventStoreDB, Core.EntityFramework, Core.ElasticSearch, Core.Kafka, Core.Scheduling, Core.WebApi and Core.Testing, each with test projects for several of them such as Core.EventStoreDB.Tests and Core.Kafka.Tests. Marten.Integration.Tests and EventSourcing.Integration.Tests sit next to them, and the solution is EventSourcing.NetCore.slnx.

The split tells you where the abstractions live. Marten, EventStoreDB, Entity Framework, Elasticsearch and Kafka each get their own adapter project, so you can read how the same ideas are expressed against each one. Section 11 of the README points to NuGet packages for getting started.

## Postgres and EventStoreDB run from docker-compose profiles with a hard-coded password

docker-compose.yml defines services behind profiles, so you start only what a sample needs. The postgres service uses the postgres:15.1-alpine image, publishes port 5432 and sets POSTGRES_PASSWORD=Password12!, which is a development value written into the file. pgadmin sits behind the postgres-ui profile and takes PGADMIN_DEFAULT_EMAIL and PGADMIN_DEFAULT_PASSWORD, with defaults admin@pgadmin.org and admin, and port 5050 unless PGADMIN_PORT overrides it.

EventStoreDB uses eventstore/eventstore:23.10.0-bookworm-slim, with EVENTSTORE_CLUSTER_SIZE=1, EVENTSTORE_RUN_PROJECTIONS=All and EVENTSTORE_START_STANDARD_PROJECTIONS=true. A comment in the file says to use the 23.10.0-alpha-arm64v8 tag if you are on an ARM processor such as Apple M1, so the default image does not suit that hardware. A jaeger service from jaegertracing/all-in-one:latest sits behind the otel profile. The credentials and the unpinned latest tag are fine for a laptop and wrong for anything you expose.

## The Dockerfile builds only the Tickets API on .NET SDK 10.0

The root Dockerfile is a multistage build starting from mcr.microsoft.com/dotnet/sdk:10.0-alpine. It copies the build props files and only the project files for Core, Core.Serialization, Core.Marten, Core.WebApi and the Tickets sample, runs dotnet restore on Sample/Tickets/Tickets.Api/Tickets.Api.csproj, then copies the source, builds in Release with no restore, and publishes to an out folder. A commented step shows where dotnet test would go.

The limit is plain: this image builds one sample. If you want to containerise the Warehouse or the Helpdesk sample, you write your own Dockerfile following this pattern, since the file copies paths specific to Tickets.

## Two training kits and eleven videos carry the explanations that the samples leave out

Samples show code, and the README adds the reasoning through a videos section of eleven talks. Titles include Keep your streams short, Let's build event store in one hour, CQRS is Simpler than you think with C#11 and NET7, How to deal with privacy and GDPR in Event-Sourced systems, Let's build the worst Event Sourcing system and Implementing Distributed Processes.

Section 7 lists two self-paced training kits, Introduction to Event Sourcing and Build your own Event Store. Workshops is also a top-level folder. Building a store from scratch is the exercise that exposes what Marten and EventStoreDB do for you, such as appending to a stream and reading it back to rebuild state, topics the README covers in its sections on streams, event storage and retrieving current state from events.

Section 12 is a long link collection with headings for projections, snapshots, versioning, storage, GDPR, conflict detection, testing, CQRS and domain driven design. It also has a heading, This is NOT Event Sourcing (but Event Streaming), which separates the two ideas.

## The last tagged release is from 2023 while commits continue

The recent releases are v21.0.0 on 2023-02-21, which extended the distributed processes examples with Choreography and Process Manager, v20.0.0 on 2023-02-18 and v19.0.0 on 2023-02-17. The repository is not archived, and its last push was on 2026-09-17. The Dockerfile references SDK 10.0, while the release titles mention C#11 and .NET 7.

That gap shapes how to read the repository. Treat the main branch as the current state and the tags as snapshots of a talk or a lesson. Directory.Packages.props centralises package versions, so check it first if a sample fails to restore on your SDK. The license is CC-BY-SA-4.0, a Creative Commons licence that carries attribution and share-alike terms, which you should read before copying large parts of the text or code into your own repository.

## Conclusion

Use this repository if you are a .NET developer who learns from runnable samples and wants to compare Marten on Postgres with EventStoreDB. Do not expect a package to reference or a migration path: the latest tagged release is v21.0.0 from February 2023. Before cloning, decide which event store you care about, because the samples are divided between the two.

## FAQ

### What is event sourcing and how does it work in EventSourcing.NetCore?

Event Sourcing stores the results of business operations as a series of events. Instead of keeping only the latest state of an entity, each state change is saved as its own event, so no business data is lost.

### Which database does EventSourcing.NetCore use for event sourcing?

The samples use two stores: Marten, which runs on Postgres, and EventStoreDB. The docker-compose.yml file starts postgres:15.1-alpine and eventstore/eventstore:23.10.0-bookworm-slim behind profiles.

### What is the difference between event sourcing and event streaming in EventSourcing.NetCore?

The README keeps a separate section titled This is NOT Event Sourcing (but Event Streaming) among its resource links. The repository itself focuses on storing business events as the source of state.

### What is the difference between event sourcing and event-driven design in EventSourcing.NetCore?

Event Sourcing is a way to persist data as events. The repository also covers event-driven design in a video titled The Light and The Dark Side of the Event-Driven Design and in distributed process samples.

## Sources

- [License: CC-BY-SA-4.0](https://github.com/oskardudycz/EventSourcing.NetCore/blob/main/LICENSE)
- [oskardudycz/EventSourcing.NetCore on GitHub](https://github.com/oskardudycz/EventSourcing.NetCore)
- [Project website](https://event-driven.io)
- [README](https://github.com/oskardudycz/EventSourcing.NetCore/blob/main/README.md)
- [Releases](https://github.com/oskardudycz/EventSourcing.NetCore/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/oskardudycz-eventsourcing-netcore
