
PipeR
A Lightweight, High-Performance Request Pipeline for .NET.
Internal Designation: PipeR Core
Developed in response to the commercialization of MediatR, PipeR provides a clean, minimal, and high-performance mediator-style pipeline. It supports composable behaviors, ASP.NET Core integration, and clean architectural boundaries. The project reflects a philosophy of reducing dependency weight while maintaining architectural elegance.
Project Milestones
8/13/2025
Project Inception
Initiated as an open-source alternative to MediatR following its transition to a commercial license model.
9/1/2025
Core Pipeline Architecture Stabilized
Implemented lightweight request/response pipeline with middleware-like extensibility.
10/18/2025
ASP.NET Core Integration
Released PipeR.Extensions.AspNetCore for seamless DI and HTTP pipeline integration.
12/5/2025
CI Pre-Release v0.0.4
Published CI builds to NuGet with structured package separation.
Project Strategy
Key Decisions
- Designed as a lightweight alternative to MediatR after its licensing change.
- Avoided unnecessary abstractions to reduce performance overhead.
- Separated core pipeline logic from ASP.NET Core integration.
- Maintained minimal dependencies to reduce package bloat.
Challenges Solved
- Ensured composable middleware-like behavior without heavy reflection.
- Balanced extensibility with simplicity.
- Maintained compatibility with existing mediator-driven architectures.
Future Plans
- Stabilize v1.0 public release.
- Expand extension packages (logging, validation, resilience).
- Introduce benchmarking comparisons against MediatR.
- Improve documentation and example repositories.
Project detail
The following detail mirrors the full wiki project write-up.
PipeR is a purpose-built middleware-style pipeline library for .NET applications, designed to streamline request/response handling within clean architectures. Inspired by the Mediator pattern (Γ la MediatR) but built with clarity, performance, and modularity in mind, PipeR empowers developers to structure business logic as a series of composable steps.
π Why Create PipeR?
PipeR was born from a combination of architectural need, performance considerations, and a shift in the open-source ecosystem surrounding .NET.
Like many .NET developers, I relied heavily on MediatR for years as the go-to library for decoupling request handling. However, the announcement by its creator Jimmy Bogard that MediatR would be transitioning to a commercial license model sparked reflection β not just about licensing, but about control, transparency, and long-term project autonomy.
This commercialization trend, also affecting libraries like AutoMapper, is well covered by Milan Jovanovic in his thoughtful commentary: βOpen Source in .NET is Changingβ.
At the same time, inspiration struck from the community. A video by Mohamad Dbouk titled βBuild Your Own Mediator in .NETβ laid out a minimalist but clear implementation of the Mediator pattern. This helped crystallize my thinking: I didnβt need to fork MediatR or wait for community reactions β I could build my own approach, one tailored to the specific patterns and performance characteristics I value in my production services.
Thus, PipeR was envisioned β not as a clone, but as a composable, high-performance middleware engine that emphasizes:
- β Explicit flow control through fluent configuration
- β Strong typing for both requests and middleware
- β Lightweight footprint with zero reflection at runtime
- β Plug-and-play middleware and validation support
- β Production resilience without third-party dependency entanglement
PipeR was born out of the desire for a more controlled, pluggable, and high-performance solution β tailored for backends where performance and traceability matter.
π§± Core Concepts
- Request Types β Define the request + response types (e.g.,
LoginUserRequest : IRequest<LoginResponse>) - Handlers β Pure handlers containing business logic
- Middleware β Pre/post-processing components injected into the pipeline (e.g., logging, metrics, validation)
- PipelineBuilder β Fluent API to register steps and compose the request execution flow
π¦ Basic Usage - PipelineBuilder
var pipeline = new PipelineBuilder()
.Use<LoggingMiddleware>()
.Use<AuthorizationMiddleware>()
.UseHandler<LoginRequestHandler>()
.Build();
var result = await pipeline.ExecuteAsync(new LoginUserRequest { ... });Each middleware gets a chance to inspect, short-circuit, or transform the request/response. Everything is strongly typed, and you remain in full control of registration order and dependency resolution.
π Request/Response Separation (CQRS-Light)
While PipeR focuses heavily on composable middleware pipelines, it also promotes a clean and consistent request/response structure. Inspired by the CQRS pattern, this approach brings clarity and separation of concerns without the complexity of full-blown CQRS implementations.
Here's how simple a controller becomes:
[HttpGet]
public async Task<ActionResult<GetAllBooksResponse>>
GetBooks([FromQuery] GetAllBooksQuery query) =>
await this.HandleRequest(query);And with the help of a base controller abstraction, you inject your IPiper dependency once and unify request routing:
public class BookControllerBase : ControllerBase
{
protected readonly IPiper _piper;
public BookControllerBase(IPiper piper)
{
_piper = piper;
}
protected async Task<ActionResult> HandleRequest<TResponse>(IRequest<TResponse> request)
{
var userIdClaim = User.FindFirst("UserId");
if (userIdClaim != null && request is BaseRequest baseRequest)
{
baseRequest.UserId = Guid.Parse(userIdClaim.Value);
return Ok(await _piper.Send(request));
}
return Forbid();
}
}π Requests and Responses
public class GetAllBooksRequest : BaseRequest
{
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 20;
public string? SearchTerm { get; set; }
}
public class GetAllBooksResponse : BaseResponse
{
public PagedResult<BookDto> Books { get; set; } = new();
}π Query + Validation Layer
public class GetAllBooksQuery : GetAllBooksRequest, IRequest<GetAllBooksResponse> {}
public class GetAllBooksValidator : AbstractValidator<GetAllBooksQuery>
{
public GetAllBooksValidator()
{
RuleFor(x => x.ApiKey)
.NotEmpty().WithMessage("A valid API Key must be provided!");
RuleFor(x => x.UserId)
.NotNull().WithMessage("User Id must be supplied!");
}
}βοΈ Abstract Request Handler
Your handlers can inherit from a base class that encapsulates common patterns, enforcing consistency and reducing duplication:
public abstract class RequestHandlerBase<TRequest, TResponse, TValidator>
: IRequestHandler<TRequest, TResponse>
where TRequest : BaseRequest, IRequest<TResponse>
where TResponse : BaseResponse, new()
where TValidator : AbstractValidator<TRequest>, new()
{
// Abstract Handle logic with optional validation
}This architecture ensures that all requests are routed, validated, and handled consistently β reducing boilerplate and centralizing behavior for cross-cutting concerns.
π Advantages Over MediatR
- π No reflection or dynamic resolution overhead
- π§© Middleware chaining using pure DI or fluent configuration
- π¬ Transparent request flow, easier debugging
- π‘οΈ Cleaner separation of concerns in complex apps
π‘ When to Use PipeR
PipeR excels in systems that:
- Need structured pipelines (like CQRS or request-response)
- Emphasize testability, modularity, and observability
- Run in high-performance or resource-constrained environments (e.g., containers, microservices)
- Desire a MediatR alternative without the baggage
π§ͺ Example Scenario: Validating and Handling a Login
// Middleware
public class ValidationMiddleware<TRequest, TResponse> : IPipelineMiddleware<TRequest, TResponse>
{
public async Task<TResponse> InvokeAsync(
TRequest request,
Func<TRequest, Task<TResponse>> next)
{
Validate(request); // throw on failure
return await next(request);
}
}
// Handler
public class LoginHandler : IRequestHandler<LoginRequest, LoginResponse>
{
public async Task<LoginResponse> Handle(LoginRequest request)
{
return new LoginResponse { Token = "abc123" };
}
}π GitHub
The PipeR project will soon be available on GitHub, alongside full documentation and integration examples.
π¦ NuGet Plans
The library will be packaged into two NuGet packages:
PipeR.Coreβ Core pipeline interfaces and enginePipeR.AspNetCoreβ an extension on top of Core for use in ASP.NET Core projects
π Coming Soon
- π MediatR compatibility bridge
- π― Benchmark comparisons
- π OpenTelemetry middleware
- π§ͺ Unit testing harnesses for pipelines and middleware
PipeR is your fast track to clean, composable, middleware-first request handling in .NET.
Filed under: .NET, CQRS, Middleware, Clean Architecture, Performance, MediatR Alternative