Request interceptors
Wrap every request with reusable steps. Turn on logging, validation and transactions once, and every command and query gets them.
MediCore is a lightweight CQRS mediator for .NET. Validation, logging and transactions run as interceptors, so your handlers only contain business logic.
$dotnet add package MediCore
MediCore gives you the mediator pattern and the cross-cutting pieces that usually come with it.
Wrap every request with reusable steps. Turn on logging, validation and transactions once, and every command and query gets them.
Publish an event once and let any number of handlers react to it.
Register handlers and interceptors in one place, with the standard .NET dependency injection you already use.
Commands, queries, notifications and interceptors each have their own interface. Your code says what it does, and swapping or testing a piece stays simple.
Built for .NET 8 with nullable reference types and XML docs, so IntelliSense explains each type as you type.
It only depends on the Microsoft.Extensions abstractions for dependency injection and logging. No extra frameworks to pull in.
Register MediCore, write a command and handler, then add an interceptor.
using MediCore;
var builder = WebApplication.CreateBuilder(args);
// Scan this assembly for handlers and interceptors
builder.Services.AddMediCore(options =>
{
options.RegisterHandlersFromAssemblyContaining<Program>();
options.AddDefaultInterceptors();
options.UseTransactionManager<MyEfTransactionManager>(); // optional — defaults to TransactionScopeManager
});
var app = builder.Build();
app.Run();public record CreateOrderCommand(string Customer) : ICommand<int>;
public class CreateOrderHandler : ICommandHandler<CreateOrderCommand, int>
{
public Task<int> Handle(CreateOrderCommand command, CancellationToken ct)
{
// Only business logic here.
return Task.FromResult(42);
}
}
// In a controller or endpoint
var orderId = await mediator.Send(new CreateOrderCommand("Varun"));public class TimingInterceptor<TRequest, TResponse>
: IRequestInterceptor<TRequest, TResponse>
{
public async Task<TResponse> Intercept(
TRequest request, RequestDelegate<TResponse> next, CancellationToken ct)
{
var started = Stopwatch.GetTimestamp();
var response = await next(); // runs the next step, then the handler
Console.WriteLine($"{typeof(TRequest).Name} took {Stopwatch.GetElapsedTime(started).TotalMilliseconds} ms");
return response;
}
}MediCore is open source and created by Varun Kumar A, a software engineer working with .NET and Angular. Questions, ideas and feedback are always welcome.
Install it, send your first command, and tell us what you think. Feedback and issues on GitHub are very welcome.
$dotnet add package MediCore