Axent.Extensions.AspNetCore 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Axent.Extensions.AspNetCore --version 1.2.0
                    
NuGet\Install-Package Axent.Extensions.AspNetCore -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Axent.Extensions.AspNetCore" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Axent.Extensions.AspNetCore" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Axent.Extensions.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Axent.Extensions.AspNetCore --version 1.2.0
                    
#r "nuget: Axent.Extensions.AspNetCore, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Axent.Extensions.AspNetCore@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Axent.Extensions.AspNetCore&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Axent.Extensions.AspNetCore&version=1.2.0
                    
Install as a Cake Tool

Axent

Axent Logo

NuGet NuGet NuGet Downloads GitHub Actions Workflow Status Quality Gate Status License

Axent is a lightweight, high-performance .NET library for implementing the CQRS pattern with minimal boilerplate. It provides a source-generated, typed request/response pipeline — currently ~2x faster than MediatR (v12.5) with fewer allocations.


Why Axent?

  • 🚀 Fast: source generated dispatch with zero reflection
  • 🧩 Minimal: very little setup
  • 🧠 Strongly typed, extensible pipelines for cross-cutting concerns
  • 🌐 First class ASP.NET Core integration
  • ⚙️ Built for modern .NET (8+)

📦 Features

  • Minimal setup and boilerplate
  • Source-generated dispatch — no reflection at runtime
  • Typed pipelines with support for generic and request-specific pipes
  • Separate marker interfaces for commands and queries (ICommand<TResponse>, IQuery<TResponse>)
  • Built-in support for transactions, logging, and error handling via pipeline options
  • ASP.NET Core integration
  • .NET 8+ optimized

Prerequisites

  • .NET 8 or later

🚀 Getting Started

1. Install Packages

dotnet add package Axent.Core --version 1.2.0
dotnet add package Axent.Extensions.AspNetCore --version 1.2.0

2. Register Services

builder.Services.AddAxent()
    .AddRequestHandlers(AssemblyProvider.Current);

3. Create a Request and Handler

  • IQuery<TResponse> for read operations
  • ICommand<TResponse> for write operations
  • IRequest<TResponse> if you don't want to differentiate
  • IRequestHandler<TRequest, TResponse> to handle them
using Axent.Abstractions;

namespace Axent.ExampleApi;

internal sealed class ExampleQuery : IQuery
{
    public required string Message { get; init; }
}

internal sealed class ExampleQueryHandler : IRequestHandler
{
    private readonly ILogger _logger;

    public ExampleQueryHandler(ILogger logger)
    {
        _logger = logger;
    }

    public ValueTask<Response> HandleAsync(RequestContext context, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Message from request '{Message}'", context.Request.Message);
        return ValueTask.FromResult(Response.Success(Unit.Value));
    }
}

4. Send a Request

Inject ISender into endpoints or application services.

app.MapGet("/api/example", async (ISender sender, CancellationToken cancellationToken) =>
{
    var response = await sender.SendAsync(new ExampleQuery { Message = "Hello World!" }, cancellationToken);
    return response.ToResult();
});

🔁 Pipelines

Pipelines allow you to add cross-cutting behavior such as:

  • Logging
  • Validation
  • Metrics
  • Authorization
  • Caching

Implement

IAxentPipe<TRequest, TResponse>

Pipes are executed in registration order before the handler.

🌐 Generic Pipe

Runs for all request types.

internal sealed class LoggingPipe : IAxentPipe
{
    private readonly ILogger<LoggingPipe> _logger;

    public LoggingPipe(ILogger<LoggingPipe> logger)
    {
        _logger = logger;
    }

    public ValueTask<Response> ProcessAsync(IPipelineChain chain, RequestContext context, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Handling {Request}", typeof(TRequest).Name);
        return chain.NextAsync(context, cancellationToken);
    }
}
Registration
builder.Services.AddAxent()
    .AddRequestHandlers(AssemblyProvider.Current)
    .AddPipe(typeof(LoggingPipe));

🎯 Request Specific Pipe

Runs only for a single request type.

internal sealed class OtherRequestPipe : IAxentPipe
{
    private readonly ILogger _logger;

    public OtherRequestPipe(ILogger logger)
    {
        _logger = logger;
    }

    public ValueTask<Response> ProcessAsync(IPipelineChain chain, RequestContext context, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Running pipe for OtherRequest");
        return chain.NextAsync(context, cancellationToken);
    }
}
Registration
builder.Services.AddAxent()
    .AddRequestHandlers(AssemblyProvider.Current)
    .AddPipe();

⚙️ Configuration

Customize behavior via AxentOptions.

builder.Services.AddAxent(options =>
{
    options.ErrorHandling = new AxentErrorHandlingOptions
    {
        EnableDetailedExceptionResponse = false
    };

    options.Logging = new AxentLoggingOptions
    {
        EnableRequestLogging = true
    };

    options.Transactions = new AxentTransactionOptions
    {
        UseTransactions = true
    };
});
Option Description Default
ErrorHandling Enables pipeline exception handling. EnableDetailedExceptionResponse includes exception details in responses. If null, exceptions propagate. null
Logging.EnableRequestLogging Logs the full request object via ILogger before processing. Avoid in production if requests contain sensitive data. false
Transactions.UseTransactions Wraps ICommand handlers in a TransactionScope. Has no effect on IQuery handlers. true
Transactions.TransactionOptions Isolation level and timeout settings. ReadCommitted, 180s
Transactions.TransactionScopeOption Interaction with ambient transactions. Required
Transactions.TransactionScopeAsyncFlowOption Controls async transaction flow. Enabled

📊 Benchmarks

Axent (Source Generated Dispatch)

BenchmarkDotNet v0.14.0, Windows 11 (10.0.26200.7840)
Unknown processor
.NET SDK 10.0.200-preview.0.26103.119
  [Host]     : .NET 8.0.23 (8.0.2325.60607), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI [AttachedDebugger]
  DefaultJob : .NET 8.0.23 (8.0.2325.60607), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
Method Mean Error StdDev Ratio RatioSD Gen0 Allocated Alloc Ratio
'SendAsync (cold)' 36.74 ns 0.741 ns 1.702 ns 1.00 0.06 0.0196 328 B 1.00
'SendAsync (warm, same instance)' 33.97 ns 0.423 ns 0.353 ns 0.93 0.04 0.0181 304 B 0.93

MediatR (v12.5.0)

BenchmarkDotNet v0.14.0, Windows 11 (10.0.26200.7840)
Unknown processor
.NET SDK 10.0.200-preview.0.26103.119
  [Host]     : .NET 8.0.23 (8.0.2325.60607), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI [AttachedDebugger]
  DefaultJob : .NET 8.0.23 (8.0.2325.60607), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
Method Mean Error StdDev Gen0 Allocated
'Send (cold)' 79.03 ns 1.526 ns 2.713 ns 0.0257 432 B
'Send (warm, same instance)' 79.21 ns 1.566 ns 3.783 ns 0.0243 408 B

🤝 Contributing

Contributions are welcome. If you find a bug, have an improvement, or want to propose a feature:

  1. Open an issue
  2. Start a discussion
  3. Submit a pull request

📄 License

This project is licensed under the Apache License 2.0. See LICENSE for details.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.2 104 3/9/2026
1.2.1 97 3/9/2026
1.2.1-alpha.2 51 3/8/2026
1.2.1-alpha.1 46 3/8/2026
1.2.0 96 3/8/2026
1.1.0 94 2/28/2026
1.1.0-alpha.3 45 2/28/2026
1.1.0-alpha.2 49 2/28/2026
1.0.1 88 2/26/2026
1.0.0 87 2/25/2026
0.0.1 87 2/25/2026