Mediator library patterns and interfaces for FSH. This project uses the Mediator source generator, NOT MediatR. Reference when implementing commands, queries, and handlers.
⚠️ FSH uses the Mediator source generator library, NOT MediatR.
These are different libraries with different interfaces. Using MediatR interfaces will cause build errors.
| Purpose | ✅ Mediator (Use This) | ❌ MediatR (Don't Use) |
|---|---|---|
| Command | ICommand<TResponse> | IRequest<TResponse> |
| Query | IQuery<TResponse> | IRequest<TResponse> |
| Command Handler | ICommandHandler<TCommand, TResponse> | IRequestHandler<TRequest, TResponse> |
| Query Handler | IQueryHandler<TQuery, TResponse> | IRequestHandler<TRequest, TResponse> |
| Notification | INotification | INotification |
| Notification Handler |
INotificationHandler<T> |
INotificationHandler<T> |
// ✅ Correct - Mediator
public sealed record CreateUserCommand(string Email, string Name) : ICommand<Guid>;
public sealed class CreateUserHandler : ICommandHandler<CreateUserCommand, Guid>
{
public async ValueTask<Guid> Handle(CreateUserCommand command, CancellationToken ct)
{
// Implementation
}
}
// ❌ Wrong - MediatR
public sealed record CreateUserCommand(string Email, string Name) : IRequest<Guid>;
public sealed class CreateUserHandler : IRequestHandler<CreateUserCommand, Guid>
{
public async Task<Guid> Handle(CreateUserCommand request, CancellationToken ct)
{
// This won't work!
}
}
// ✅ Correct - Mediator
public sealed record GetUserQuery(Guid Id) : IQuery<UserDto>;
public sealed class GetUserHandler : IQueryHandler<GetUserQuery, UserDto>
{
public async ValueTask<UserDto> Handle(GetUserQuery query, CancellationToken ct)
{
// Implementation
}
}
| Aspect | Mediator | MediatR |
|---|---|---|
| Return type | ValueTask<T> | Task<T> |
| Parameter name | command / query | request |
| Registration | Source generated | Runtime reflection |
| Performance | Faster (compile-time) | Slower (runtime) |
// In endpoint
public static async Task<IResult> Handle(
CreateUserCommand command,
IMediator mediator, // Same interface name as MediatR
CancellationToken ct)
{
var result = await mediator.Send(command, ct);
return TypedResults.Created($"/users/{result}");
}
// In Program.cs
builder.Services.AddMediator(options =>
{
options.Assemblies =
[
typeof(IdentityModule).Assembly,
typeof(MultitenancyModule).Assembly,
// Add your module assemblies here
];
});
IRequest<T> not foundCause: Using MediatR interface
Fix: Change to ICommand<T> or IQuery<T>
IRequestHandler<T,R> not foundCause: Using MediatR interface
Fix: Change to ICommandHandler<T,R> or IQueryHandler<T,R>
Cause: Assembly not registered in AddMediator
Fix: Add assembly to options.Assemblies array
Task<T> vs ValueTask<T>Cause: Using MediatR return type
Fix: Change handler return type to ValueTask<T>
// ✅ Correct
using Mediator;
// ❌ Wrong
using MediatR;