Skip to content

Event Types and Discovery

Every event in EventSourcingKit has two identities: the C# type you work with in code, and the event type name stored in EventSourcingDB. Discovery is the mechanism that connects the two, so you can store and read strongly typed events without registering each one by hand.

Marking a Type as an Event

A type becomes an event by implementing the IEventData marker interface and carrying an [EventType] attribute:

[EventType("book-registered")]
public record BookRegistered(
    Guid BookId,
    string Title,
    string Author
) : IEventData;

IEventData is what discovery looks for; [EventType] supplies the stable type name that is persisted with every event and used when reading it back. The name is part of your event store's contract, so choose it deliberately.

How Discovery Works

When you call AddEventSourcingKit, you pass the assemblies that contain your events. At startup, EventSourcingKit scans those assemblies for every non-abstract type that implements IEventData and builds a map from each [EventType] name to its C# type.

That map is what lets the library hand your reducers a strongly typed Event<T> and turn stored events back into the right record. A type without an [EventType] attribute cannot be resolved, and the library throws an InvalidOperationException that names the offending type.

Inspecting the Event Types in a Store

A store may also contain event types that no longer exist in your code, for example events written by an earlier version of your service or by a different application sharing the same store. EventSourcingKit represents every type it knows about as an EventType:

public record EventType(
    string Type,
    Type? EventDataType,
    bool IsPhantom,
    JsonElement? Schema
);

EventDataType is null when the type is not present in your code, and IsPhantom flags exactly that situation. You can enumerate a store's types with GetEventTypes to audit which events your code can and cannot handle.

Catch unknown events early

Enable RequireEvents to make EventSourcingKit throw at startup if the store contains event types that are not discovered in your code. This turns a silent gap into an immediate, visible failure. See Configuration.

For More Information