Build Performant APIs Fast!
Search
⌘ K
Main navigation menu
Color Scheme
Open main sidebar
- Event Bus
Close sidebar
Search
⌘ K
-
- Get Started
- Security
- Model Binding
- Validation
- Dependency Injection
- Domain Entity Mapping
- File Handling
- Response Caching
- Rate Limiting
- Swagger Support
- Post Processors
- Event Bus
- Command Bus
- Job Queues
- Remote Procedure Calls
- Server Sent Events
- Exception Handler
- Integration & Unit Testing
- Configuration Settings
- Misc Conveniences
- API Versioning
- Idempotency
- Native AOT
- Scaffolding
- The Cookbook
In-Process Event Bus Pattern (Pub/Sub)
If you’d like to take an event driven approach to building your application, you have the option to publish events and have completely decoupled Event-Handlers take action when events are published. An event can have more than one handler and has a one-to-many relationship. Due to the nature of pub/sub event bus pattern, handlers cannot return any results back to the caller/publisher.
# 1. Define An Event Model/ DTO
This is the data contract that will be delivered to the subscribers/event-handlers.
public class OrderCreatedEvent
{
public string OrderID { get; set; }
public string CustomerName { get; set; }
public decimal OrderTotal { get; set; }
}
# 2. Define An Event Handler
This is the code that will be executed when events of the above DTO type gets published.
public class OrderCreationHandler : IEventHandler<OrderCreatedEvent>
{
private readonly ILogger _logger;
public OrderCreationHandler(ILogger<OrderCreationHandler> logger)
{
_logger = logger;
}
public Task HandleAsync(OrderCreatedEvent eventModel, CancellationToken ct)
{
_logger.LogInformation($"order created event received:[{eventModel.OrderID}]");
return Task.CompletedTask;
}
}
You can create as many implementations of IEventHandler
# 3. Publish The Event
Simply hand in an event model to the PublishAsync() method.
public class CreateOrderEndpoint : Endpoint<CreateOrderRequest>
{
public override void Configure()
{
Post("/sales/orders/create");
}
public override async Task HandleAsync(CreateOrderRequest req, CancellationToken ct)
{
var orderID = await orderRepo.CreateNewOrder(req);
await PublishAsync(new OrderCreatedEvent
{
OrderID = orderID,
CustomerName = req.Customer,
OrderTotal = req.OrderValue
});
await Send.OkAsync();
}
}
# The PublishAsync() Method
The PublishAsync() method has an overload that will take a Mode enum that lets you specify whether to wait for all subscribers to finish; wait for any subscriber to finish; or wait for none of the subscribers to finish.
For example, you can publish an event in a fire-n-forget manner with the following:
await PublishAsync(eventModel, Mode.WaitForNone);
The default mode is Mode.WaitForAll which will await all subscribers. I.e. execution will only continue after each and every subscriber of the event has completed their work.
# Publish From Anywhere
It is possible to publish events even from outside of endpoints by marking the event model with the IEvent interface, which would provide PublishAsync() as an extension method.
public class OrderCreatedEvent : IEvent { ... }
await new OrderCreatedEvent
{
OrderID = "12345",
CustomerName = "scarlet johanson",
OrderTotal = 123.45m
}
.PublishAsync(Mode.WaitForAll);
# Dependency Injection
Dependencies in event handlers can be resolved as described here.
# Event Bus Without FastEndpoints
The Event Bus can be used independently of the FastEndpoints library, even with Blazor WASM projects. Simply install the messaging library like so:
terminal
Copied!
Copy code
dotnet add package FastEndpoints.Messaging
Register the messaging services with the IOC container as shown in the following console application example:
Program.cs
Copied!
Copy code
using FastEndpoints; //add this
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var bld = Host.CreateApplicationBuilder();
bld.Services.AddMessaging(); //add this
var host = bld.Build();
host.Services.UseMessaging(); //add this
var appStartedEvent = new AppStarted();
await appStartedEvent.PublishAsync();
await host.RunAsync();
sealed class AppStarted : IEvent
{
public string Message => "Welcome to the App!";
}
sealed class AppStartedHandler(ILogger<AppStartedHandler> logger) : IEventHandler<AppStarted>
{
public Task HandleAsync(AppStarted e, CancellationToken c)
{
logger.LogInformation("{@msg}", e.Message);
return Task.CompletedTask;
}
}
Previous ← Pre / Post Processors
Next Command Bus →
© FastEndpoints 2026