A lightweight and minimal mediator library for .NET. Implement request/response and notification patterns effortlessly with clean, readable code.
dotnet add package Interlink
Interlink gives you the core benefits of a mediator pattern without the boilerplate bloat.
Minimal footprint with zero unnecessary dependencies. Built to stay out of your way and run blazing fast on .NET Standard 2.0+ through .NET 10.
Clean request/response pattern with strong typing. Encapsulate queries and commands using IRequest<T> and dedicated handlers.
Broadcast domain events to multiple handlers with zero friction using the simple INotification + IPublisher model.
Add cross-cutting concerns (logging, validation, timing, etc.) with ordered pipeline behaviors. Control execution order via attributes or configuration.
Run logic before the pipeline and after a successful handler execution. Automatically discovered and registered by AddInterlink().
One-line setup with assembly scanning. Optional custom service factory and full control over pipeline behavior ordering.
Keep the core package minimal. Add only the features you need.
Built-in LoggingBehavior that logs request start, duration, and exceptions.
Interlink.Extensions.Logging
Automatic validation pipeline. Throws ValidationException on failure.
Interlink.Extensions.Validation
Exception filter that maps HandlerNotFoundException → 404 and validation errors → 400.
Interlink.AspNetCore
Roslyn analyzer that warns (ILINK001) when a request has no matching handler.
Interlink.Analyzers
See how straightforward it is to define a query and handle it with Interlink.
public record GetUserQuery(int Id) : IRequest<UserDto>;
public class GetUserQueryHandler
: IRequestHandler<GetUserQuery, UserDto>
{
public async Task<UserDto> Handle(
GetUserQuery request,
CancellationToken cancellationToken)
{
// Fetch user logic here...
return new UserDto(request.Id, "John Doe");
}
}
[ApiController]
[Route("api/users")]
public class UsersController(ISender sender) : ControllerBase
{
[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
var query = new GetUserQuery(id);
var result = await sender.Send(query);
return Ok(result);
}
}