Getting Started
Foundatio Mediator is a high-performance, convention-based mediator for .NET applications. This guide will walk you through the basic setup and your first handler.
Installation
Install the Foundatio.Mediator NuGet package:
dotnet add package Foundatio.Mediator
<PackageReference Include="Foundatio.Mediator" Version="1.0.0" />
Install-Package Foundatio.Mediator
Basic Setup
1. Register the Mediator
Add the mediator to your dependency injection container:
// Program.cs (Minimal API)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMediator();
var app = builder.Build();
// Program.cs (Generic Host)
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddMediator();
})
.Build();
// Startup.cs (Traditional ASP.NET Core)
public void ConfigureServices(IServiceCollection services)
{
services.AddMediator();
// ... other services
}
2. Create Your First Message
Define a simple message:
public record Ping(string Text);
3. Create a Handler
Create a handler class following the naming conventions:
public static class PingHandler
{
public static string Handle(Ping msg)
{
return $"Pong: {msg.Text}";
}
}
4. Use the Mediator
Inject and use the mediator in your application:
public class MyService
{
private readonly IMediator _mediator;
public MyService(IMediator mediator)
{
_mediator = mediator;
}
public void DoSomething()
{
// Sync call - works when all handlers and middleware are sync
var result = _mediator.Invoke<string>(new Ping("Hello"));
Console.WriteLine(result); // Output: "Pong: Hello"
}
public async Task DoSomethingAsync()
{
// Async call - works with both sync and async handlers
var result = await _mediator.InvokeAsync<string>(new Ping("Hello"));
Console.WriteLine(result); // Output: "Pong: Hello"
}
}
Handler Conventions
Foundatio Mediator uses simple naming conventions to discover handlers automatically:
Class Names
Handler classes must end with:
Handler
Consumer
Method Names
Valid handler method names:
Handle
/HandleAsync
Handles
/HandlesAsync
Consume
/ConsumeAsync
Consumes
/ConsumesAsync
Method Signatures
- First parameter: The message object (required)
- Remaining parameters: Injected via dependency injection
- Return type: Any type including
void
,Task
,Task<T>
Examples
Synchronous Handler
public record GetGreeting(string Name);
public static class GreetingHandler
{
public static string Handle(GetGreeting query)
{
return $"Hello, {query.Name}!";
}
}
// Usage
var greeting = mediator.Invoke<string>(new GetGreeting("World"));
Asynchronous Handler
public record SendEmail(string To, string Subject, string Body);
public class EmailHandler
{
public async Task HandleAsync(SendEmail command)
{
// Simulate sending email
await Task.Delay(100);
Console.WriteLine($"Email sent to {command.To}");
}
}
// Usage
await mediator.InvokeAsync(new SendEmail("user@example.com", "Hello", "World"));
Handler with Dependency Injection
public class UserHandler
{
private readonly IUserRepository _repository;
private readonly ILogger<UserHandler> _logger;
public UserHandler(IUserRepository repository, ILogger<UserHandler> logger)
{
_repository = repository;
_logger = logger;
}
public async Task<User> HandleAsync(GetUser query, CancellationToken cancellationToken)
{
_logger.LogInformation("Getting user {UserId}", query.Id);
return await _repository.GetByIdAsync(query.Id, cancellationToken);
}
}
Next Steps
Now that you have the basics working, explore more advanced features:
- Handler Conventions - Learn all the discovery rules
- Result Types - Using Result<T> for robust error handling
- Middleware - Adding cross-cutting concerns
- Examples - See practical examples
LLM-Friendly Documentation
For AI assistants and Large Language Models, we provide optimized documentation formats:
- 📜 LLMs Index - Quick reference with links to all sections
- 📖 Complete Documentation - All docs in one LLM-friendly file
These files follow the llmstxt.org standard and contain the same information as this documentation in a format optimized for AI consumption.
Common Issues
Handler Not Found
If you get a "handler not found" error:
- Ensure your class name ends with
Handler
orConsumer
- Ensure your method name follows the naming conventions
- Ensure the first parameter matches your message type exactly