Skip to content

Event Module

A. Shafie edited this page Nov 23, 2023 · 12 revisions

Events

Events are informative messages designed to notify various parts of a system about certain occurrences. A distinct feature of events compared to commands and queries is that they can have multiple main handlers, allowing several operations or components of your system to react to a single event.

Event Contracts

To define your own events, implement the IEvent interface:

// A simple event representation
public class ProductCreatedEvent : IEvent
{
    public long Id { get; set; }
}

Event Handler Contracts

Handlers process or act upon events. Due to the nature of events, they can have multiple handlers, which means different components of your system can respond simultaneously to an event.

Asynchronous Event Handler

// Sample asynchronous event handler
public class ProductCreatedEventHandler1 : IEventHandler<ProductCreatedEvent>
{
    public Task HandleAsync(ProductCreatedEvent @event, CancellationToken cancellationToken = default)
    {
        // Handle the event here...
    }
}

// Another sample asynchronous event handler for the same event
public class ProductCreatedEventHandler2 : IEventHandler<ProductCreatedEvent>
{
    public Task HandleAsync(ProductCreatedEvent @event, CancellationToken cancellationToken = default)
    {
        // Handle the event here...
    }
}

Event Mediator

Use the IEventMediator to publish events to their respective handlers. This ensures that all relevant handlers are informed of an event occurrence.

public interface IEventMediator
{
    Task PublishAsync(IEvent @event, CancellationToken cancellationToken = default);
    Task PublishAsync<TEvent>(TEvent @event, CancellationToken cancellationToken = default) where TEvent : IEvent;
}

Event Pre-Handlers

Pre-handlers are executed before the main event handlers, useful for activities like validation or logging.

Pre-Handler for a Specific Event Type

public class ProductEventPreHandler : IEventPreHandler<ProductCreatedEvent>
{
    public Task PreHandleAsync(ProductCreatedEvent @event, CancellationToken cancellationToken = default)
    {
        // Logic before the main event handler...
    }
}

Global Pre-Handler

public class GlobalEventPreHandler : IEventPreHandler
{
    public Task PreHandleAsync(IEvent @event, CancellationToken cancellationToken = default)
    {
        // Logic before any event handler...
    }
}

Event Post-Handlers

Post-handlers run after the main event handlers, typically for activities like logging, notifications, or other follow-up actions.

Post-Handler for a Specific Event Type

public class ProductEventPostHandler : IEventPostHandler<ProductCreatedEvent>
{
    public Task PostHandleAsync(ProductCreatedEvent @event, CancellationToken cancellationToken = default)
    {
        // Logic after the main event handler...
    }
}

Global Post-Handler

public class GlobalEventPostHandler : IEventPostHandler
{
    public Task PostHandleAsync(IEvent @event, CancellationToken cancellationToken = default)
    {
        // Logic after any event handler...
    }
}

Event Error Handlers

These handlers are activated when there's an exception during event processing. They offer a centralized way to manage and respond to errors.

Error Handler for a Specific Event Type

public class ProductEventErrorHandler : IEventErrorHandler<ProductCreatedEvent>
{
    public Task HandleErrorAsync(ProductCreatedEvent @event, Exception exception, CancellationToken cancellationToken = default)
    {
        // Handle the error for a specific event type here...
    }
}

Global Error Handler

public class GlobalEventErrorHandler : IEventErrorHandler
{
    public Task HandleErrorAsync(IEvent @event, Exception exception, CancellationToken cancellationToken = default)
    {
        // Handle the error for any event type...
    }
}

Filtering Event Handlers on Publish

Event handlers can be filtered based on a custom condition. For example, you may wish only to execute those event handlers inheriting from the IHighPriorityEventHandler interface.

// Example of using EventMediationSettings to filter event handlers
// that implement the IHighPriorityEventHandler interface

await eventMediator.PublishAsync(@event, new EventMediationSettings
{
	HandlerFilter = type => type.IsAssignableTo(typeof(IHighPriorityEventHandler))
});

Clone this wiki locally