AotCqrs 1.0.3
See the version list below for details.
dotnet add package AotCqrs --version 1.0.3
NuGet\Install-Package AotCqrs -Version 1.0.3
<PackageReference Include="AotCqrs" Version="1.0.3" />
<PackageVersion Include="AotCqrs" Version="1.0.3" />
<PackageReference Include="AotCqrs" />
paket add AotCqrs --version 1.0.3
#r "nuget: AotCqrs, 1.0.3"
#:package AotCqrs@1.0.3
#addin nuget:?package=AotCqrs&version=1.0.3
#tool nuget:?package=AotCqrs&version=1.0.3
AotCqrs
A blazing fast, reflection-free, AOT-friendly CQRS Mediator library for modern .NET, powered by C# Source Generators.
What is AotCqrs?
AotCqrs is a library that provides a simple way to implement the Mediator and CQRS patterns in your .NET applications, much like the popular MediatR library.
However, its core design principle is performance and compatibility with modern .NET technologies, especially Ahead-Of-Time (AOT) compilation and assembly trimming. It completely avoids runtime reflection by leveraging C# Source Generators to create highly optimized "glue" code at compile time.
This makes it an ideal choice for:
- High-performance ASP.NET Core Minimal APIs.
- Applications targeting NativeAOT.
- Any scenario where startup time and runtime performance are critical.
Key Features
- 🚀 High Performance: Zero runtime reflection. Requests are dispatched via a compile-time generated, highly optimized
switch
expression. - 📦 AOT & Trimming Safe: Designed from the ground up to work flawlessly with .NET's trimming and NativeAOT compilation.
- ✍️ Simple & Familiar API: If you've used MediatR, you'll feel right at home with
IRequest
,IRequestHandler
, andIMediator
. - ✅ Compile-Time Safety: The source generator connects requests to their handlers during compilation, reducing the chance of runtime "handler not found" errors.
Why AotCqrs over MediatR?
While MediatR is a fantastic library, its reliance on reflection poses challenges for AOT compilation and can impact performance. AotCqrs addresses these specific issues.
Feature | MediatR (Reflection-based) | AotCqrs (Source-Generated) |
---|---|---|
Dispatch Mechanism | Runtime Reflection, Assembly Scan | Compile-time generated switch |
AOT/Trimming | Can be problematic; requires configuration | Fully Compatible & Safe |
Performance | Good | Excellent / Blazing Fast |
Startup Cost | Scans assemblies on startup | Zero |
Installation
Install the package from NuGet:
dotnet add package AotCqrs
Getting Started
Using AotCqrs is a simple, four-step process.
1. Define your Requests (Commands & Queries)
Create a record or class that implements ICommand
(for requests that don't return a value) or IQuery<TResponse>
(for requests that do).
// Features/Users/CreateUser.cs
using AotCqrs;
// A command to create a user. It implements ICommand, which means it returns Unit.
public record CreateUserCommand(string Name) : ICommand;
2. Create Handlers
Create a class that implements IRequestHandler<TRequest>
or IRequestHandler<TRequest, TResponse>
.
This is the most important part: You must mark your handler class with the [AotCqrsHandler]
attribute. This is how the source generator discovers it.
// Features/Users/CreateUserCommandHandler.cs
using AotCqrs;
[AotCqrsHandler] // <-- This attribute is crucial!
public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand>
{
private readonly ILogger<CreateUserCommandHandler> _logger;
public CreateUserCommandHandler(ILogger<CreateUserCommandHandler> logger)
{
_logger = logger;
}
public Task<Unit> Handle(CreateUserCommand request, CancellationToken cancellationToken)
{
_logger.LogInformation("Creating user with name: {Name}", request.Name);
// Your business logic here...
return Task.FromResult(Unit.Value);
}
}
3. Register Services
In your Program.cs
, call the AddAotCqrs()
extension method. The source generator automatically creates this method for you and includes the registration for all discovered handlers.
// Program.cs
using AotCqrs; // <-- Make sure to add this using directive
var builder = WebApplication.CreateBuilder(args);
// This one line registers the mediator and all handlers marked with [AotCqrsHandler].
builder.Services.AddAotCqrs();
var app = builder.Build();
// ... rest of your Program.cs
4. Send Requests
Inject IMediator
into your controllers, Minimal API endpoints, or other services and use the Send
method.
// Program.cs (Minimal API example)
using Microsoft.AspNetCore.Mvc;
// ...
app.MapPost("/users", async (CreateUserCommand command, [FromServices] IMediator mediator) =>
{
await mediator.Send(command);
return Results.Ok($"User '{command.Name}' created.");
});
app.Run();
How It Works: The Magic of Source Generators
When you build your project, the AotCqrs source generator runs and does two things:
- It scans your code for any class marked with
[AotCqrsHandler]
. - It generates two files on the fly:
DependencyInjection.g.cs
: Contains theAddAotCqrs()
extension method, which explicitly registersIMediator
and every single handler it found. This makes it completely trimmer-friendly.Mediator.g.cs
: Contains the implementation ofIMediator
, which uses a highly optimizedswitch
expression to route incoming requests to the correct, DI-resolved handler.
This entire process happens at compile time, resulting in clean, efficient, and boilerplate-free C# code with no runtime reflection overhead.
Contributing
Contributions are welcome! If you find a bug or have a feature request, please open an issue.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.