Event handlers are the objects that actually react to domain events flowing through a subscription. Each subscription can have any number of handlers attached to it; Eventuous fans every received event out to all registered handlers and collects their results. Handlers are plain classes — they carry no subscription-specific state and can be reused across subscriptions.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Eventuous/eventuous/llms.txt
Use this file to discover all available pages before exploring further.
IEventHandler
All handlers must implement IEventHandler:
DiagnosticName identifies the handler in telemetry output. HandleEvent receives a context object that carries the deserialized message and its metadata, processes it, and returns a status value.
BaseEventHandler
BaseEventHandler is an abstract convenience class that implements IEventHandler. It sets DiagnosticName to the concrete class name automatically:
BaseEventHandler when you need complete control over dispatch — for example, when building a projector base class.
EventHandler — typed dispatch
The most common starting point is EventHandler, which extends BaseEventHandler with a typed handler registration mechanism:
On<T> for every event type you want to handle:
HandleTypedEvent<T> delegate is:
On<T> registers an internal dispatch entry. At runtime, HandleEvent looks up the event’s Type in that dictionary and invokes the correct handler. Events whose type has no registered handler return EventHandlingStatus.Ignored without any allocation.
EventHandlingStatus
EventHandlingStatus values from all handlers and uses them to decide whether to acknowledge or negatively-acknowledge the event with the broker.
IMessageConsumeContext
Every handler receives an IMessageConsumeContext, which exposes the full envelope around the event:
| Property | Type | Description |
|---|---|---|
Message | object? | Deserialized event payload |
MessageType | string | Event type name from the stream |
ContentType | string | Content-type header (e.g. application/json) |
Stream | StreamName | Stream the event was read from |
EventNumber | ulong | Position within the originating stream |
StreamPosition | ulong | Position in the subscription stream |
GlobalPosition | ulong | Position in the global event log |
Sequence | ulong | In-process sequence number (subscription-local) |
Created | DateTime | When the event was written (UTC) |
Metadata | Metadata? | Message metadata |
SubscriptionId | string | Identifier of the owning subscription |
CancellationToken | CancellationToken | Propagated from the subscription worker |
MessageConsumeContext<T> is the typed variant delivered to HandleTypedEvent<T> delegates. Its Message property is typed as T instead of object.
Writing a handler
Derive fromEventHandler, inject your dependencies, and register one On<T> call per event type in the constructor:
Registration options
SubscriptionBuilder provides several overloads for attaching handlers:
AddCompositionEventHandler:
SubscriptionId key, so two subscriptions can both register MyHandler and receive separate instances.