Skip to content

Publishing Events

Many systems need to forward events to the outside world: to a message broker, a search index, an email service, or another bounded context. EventSourcingKit has no dedicated publisher, and it does not need one. Publishing reuses the same machinery as projecting: you implement a projector that sends events wherever you want.

A Projector Is a Publisher

The observer that drives projections hands every stored event to every registered IProjector. A projection happens to write to a read model, but a projector can do anything with an event, including publishing it:

using EventSourcingKit;
using EventSourcingKit.Projecting;

public class BrokerPublisher(IMessageBroker broker) : IProjector
{
    public Task Project<TEvent>(
        Event<TEvent> @event,
        CancellationToken cancellationToken
    ) where TEvent : class, IEventData =>
        broker.Publish(@event.Type, @event.Data, cancellationToken);
}

Here IMessageBroker stands for whatever transport you use. Register the projector with AddProjector:

.AddProjector<BrokerPublisher>()

From then on, the observer delivers every event to your publisher, in order, and only advances its checkpoint once your Project method returns.

Delivery Guarantees

Because publishing rides on the observer, it inherits the observer's behavior:

  • Events are delivered in order, one at a time.
  • Delivery is at-least-once: if your application restarts after publishing but before the checkpoint is stored, the event is delivered again. Make your downstream handling idempotent so a repeated event is harmless.
  • A failing publish is retried with backoff before the observer stops, so a transient broker outage does not skip events.

For More Information