Replaying into State¶
A stream of events tells you everything that happened, but most of the time you want the current state of an entity: is this book checked out, and by whom? EventSourcingKit builds that state for you by replaying a subject's events through reducers.
Defining the State¶
State is a record that derives from State<TId>, where TId is the type of the entity's identifier. It holds only the fields you care about:
using EventSourcingKit.Replaying;
public record BookState : State<Guid>
{
public string Title { get; init; } = "";
public string Author { get; init; } = "";
public bool IsCheckedOut { get; init; }
public Guid? CheckedOutBy { get; init; }
}
Defining the Reducers¶
A reducer says how a single event changes the state, and you write one per event type. The first event uses an ICreateReducer, which builds the initial state; every subsequent event uses an IUpdateReducer, which evolves it:
using EventSourcingKit;
using EventSourcingKit.Replaying;
public class BookRegisteredReducer
: ICreateReducer<BookState, Guid, BookRegistered>
{
public BookState Create(Event<BookRegistered> @event) =>
new()
{
Id = @event.Data.BookId,
Title = @event.Data.Title,
Author = @event.Data.Author
};
}
public class BookCheckedOutReducer
: IUpdateReducer<BookState, Guid, BookCheckedOut>
{
public BookState Apply(BookState state, Event<BookCheckedOut> @event) =>
state with { IsCheckedOut = true, CheckedOutBy = @event.Data.UserId };
}
Reducers are discovered automatically from the assemblies you registered, so there is nothing else to wire up. Each reducer receives a strongly typed Event<T>, giving you direct access to the event's Data.
Replaying to the Current State¶
With state and reducers in place, ask the event store to replay a subject:
ReplayToCurrentState folds every event under the subject into a single, up-to-date BookState. This is the ideal way to load an entity before making a decision – for example, to confirm that a book is available before you store a BookCheckedOut event.
For More Information¶
- State and Reducers explains the full set of reducer types.
- Projecting builds read models that update continuously, rather than on demand.