Skip to footer content
Iron Academy Logo
Learn C#
Learn C#

Other Categories

Event Sourcing Core Concepts

Derek Comartin
11m 31s

Event sourcing is a powerful yet complex pattern often used in modern software architecture, particularly with C# and .NET Core applications. To fully grasp how to implement event sourcing, we’ll walk through the key principles as explained by Derek Comartin from CodeOpinion.com in his video "Event Sourcing Core Concepts".

If you're looking to better understand event store concepts, domain driven design, or how to build event sourced systems, you're in the right place. Let’s dive in!

Introduction to Event Sourcing

At the beginning (0:00), Derek discusses the confusion around event sourcing and associated core concepts. He defines event sourcing as not just "capturing the current state," but storing events — capturing every change that happens to your domain model in an append-only log.

This way, you maintain a complete history of your system’s state changes. Instead of persisting just the final state, you persist events that reflect the business logic that occurred​.

Events: Capturing Business Facts

At 0:33, Derek explains what an event truly is. An event represents something that has already occurred within the system — a business fact. For instance, a "ProductReceived" event would contain the quantity received and the date.

Derek stresses that when you store events, they must be named using a naming convention that reflects past tense, such as "Product Shipped" or "Inventory Adjusted"​. In an event schema, you might have fields like public Guid Id, public string Name, and timestamps.

Understanding Csharp Event Sourcing 1 related to Events: Capturing Business Facts

Each event should also have a unique identifier, crucial for an append only storage system where you're appending events to an event stream.

Event Streams: Organizing Events

At 2:02, Derek transitions into event streams. He draws a comparison with a relational database table but explains that in event sourcing, all the events related to a domain object (such as an inventory item) belong to the same event stream.

Each event stream ties to a specific entity — often defined by a public Guid Id and a string Name. For example, a product with SKU ABC123 would have its own stream containing persisted events like receiving or shipping.

Derek suggests that when you model these, think in terms of aggregate roots and domain objects, borrowing from domain driven design concepts​.

Modeling the lifecycle — whether short-lived or long-lived — helps optimize the number and size of streams. This is crucial for improving performance in complex systems​.

Projections and Read Models

At 4:12, Derek introduces projections and the read model. Since your event sourced system captures events rather than just the current state, you must replay events to answer questions like "What is the current inventory quantity?"

To build read models, you process events from the stream. For example, using private void Apply(Event e) or similar, you increment or decrement the stock based on event handlers for each event type.

Derek illustrates how to build a read model in a document database or a relational database — perhaps one projection simply shows quantity on hand, another shows shipping history.

This reflects command query responsibility segregation (CQRS): separating the write operations (commands) from the read operations (queries)​.

Projections for Write Models

At 6:48, Derek shows how to apply projections on the write side too. This is crucial for validating actions before they are allowed to happen.

In a command handler, before shipping products, you need to verify that enough quantity exists. Derek uses a method like private void Apply(Listevents) to rebuild the necessary state.

Fields like public int Version help track the stream’s evolution, ensuring eventual consistency​.

Understanding Csharp Event Sourcing 2 related to Projections for Write Models

This practical implementation helps enforce business logic when handling new events, ensuring your system only acts on valid state transitions.

Subscriptions: Reacting to New Events

At 8:01, Derek talks about subscriptions. Subscriptions let event consumers listen for new events and react.

For instance, a projector might subscribe to an event stream and update a read model when it sees a "Product Shipped" event. Alternatively, a publisher might listen for events and publish them to external systems like RabbitMQ or Kafka, integrating with other services.

Understanding Csharp Event Sourcing 3 related to Subscriptions: Reacting to New Events

Derek describes subscriptions not only for updating internal models but also for data distribution across separate event systems, preserving eventual consistency​.

This shows another major benefit of event driven architecture: your services remain eventually consistent but independently scalable.

Core Concepts Recap

At 9:21, Derek summarizes the core concepts:

  • Events capture facts.

  • Event Streams organize events by entity.

  • Projections turn streams into queryable read models or actionable write models.

  • Subscriptions allow services to react and update accordingly​.

He highlights that you persist events in an append-only log, maintain an audit trail, and replay events when necessary.

Snapshots and Optimization

At 9:39, Derek addresses snapshotting. Although often discussed alongside event sourcing, he clarifies that snapshots are a performance optimization rather than a core requirement​.

Snapshots reduce the overhead of replaying all events by saving a partial state periodically, but the complete history still exists via the append only log.

Key Distinction: Event Sourcing vs Event Driven Architecture

At 10:00, Derek warns about a common misconception: event sourcing and event driven architecture are different! Tools like Kafka help with data distribution, but true event sourcing focuses on recording domain events as an immutable audit trail.

Understanding the distinction is crucial when you integrate event sourcing into your complex systems.

Conclusion

Following Derek Comartin’s video, it’s clear that event sourcing is about recording every change as an event, not just the final state. By storing events in an append-only storage system, you build a rich event schema that provides an audit trail, flexibility for querying events, and robust support for command query responsibility segregation.

Whether you’re dealing with C# event sourcing in .NET Core or any other platform, Derek’s structured explanation of core concepts, event handlers, private sets, protected sets, and applying events like private void Apply() in your models is incredibly valuable.

If you’re working on building a resilient domain model, improving your storage system, or creating complex patterns with several benefits like eventual consistency, studying Derek’s approach is a must. Do look out his YouTube channel for more insightful videos.

Hero Worlddot related to Event Sourcing Core Concepts
Hero Affiliate related to Event Sourcing Core Concepts

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!