CQRSharp.Core 3.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package CQRSharp.Core --version 3.1.0
                    
NuGet\Install-Package CQRSharp.Core -Version 3.1.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="CQRSharp.Core" Version="3.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CQRSharp.Core" Version="3.1.0" />
                    
Directory.Packages.props
<PackageReference Include="CQRSharp.Core" />
                    
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 CQRSharp.Core --version 3.1.0
                    
#r "nuget: CQRSharp.Core, 3.1.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 CQRSharp.Core@3.1.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=CQRSharp.Core&version=3.1.0
                    
Install as a Cake Addin
#tool nuget:?package=CQRSharp.Core&version=3.1.0
                    
Install as a Cake Tool

CQRSharp

NuGet version (CQRSharp) CodeQL

Alt

A lightweight, extensible, and attribute-driven Command Query Responsibility Segregation (CQRS) framework for .NET applications, with complete Native AOT support.

A Roslyn source generator wires up dispatching and registration at compile time, so there is no runtime reflection and the whole framework is trimming- and Native-AOT-friendly.

For more information, see the CQRSharp project page.


Features

  • Native AOT & trimming-safe — a Roslyn source generator wires up all dispatch and registration at compile time; zero runtime reflection.
  • Attribute-driven — define commands, queries, streaming requests, and notifications with simple marker interfaces and handlers.
  • One façade — dispatch everything through ICqrsDispatcher (Send / Stream / Publish).
  • Build-time analyzers — catch missing handlers, the wrong dispatch method, and mis-wired pipeline exemptions as you type (CQRA diagnostics), with code fixes.
  • Opt-in pipeline behaviors — validation, resilience/retries, timeouts, rate limiting, idempotency, unit-of-work, and logging via AddCqrsPipelinePack, composed order-insensitively through the fluent AddCqrsGenerated(b => ...) builder.
  • Reliable messaging — a background task queue and a transactional outbox with at-least-once delivery and distributed-tracing propagation.
  • Batteries-included persistence — drop-in in-memory, Redis (CQRSharp.Redis), and EF Core (CQRSharp.EntityFrameworkCore) stores for both the outbox and request idempotency; no hand-written atomic-claim code required.
  • Fail-fast configuration — a startup validator surfaces silent mis-wiring (an outbox with no store, a non-transactional unit of work, outbox-bypassing notifications) as loud errors at host start instead of at first request.
  • Introspection — a diagnostics API and health checks that describe exactly how each request is bound.

Installation

dotnet add package CQRSharp

The CQRSharp meta-package pulls in the abstractions, core runtime, and the source generator for a plug-and-play setup. On projects with ImplicitUsings enabled (the .NET 8+ default) it also ships global usings for the authoring surface, so the snippets below need no using directives — CommandBase, ICommandHandler<>, CommandResult, ICqrsDispatcher, AddCqrsGenerated, and friends are already in scope. (Opt out with <CQRSharpImplicitUsings>false</CQRSharpImplicitUsings>.)

For durable outbox and idempotency persistence, add the integration package for your backing store (the core package ships in-memory stores for development and single-node use out of the box):

dotnet add package CQRSharp.Redis                 # Redis-backed outbox + idempotency stores (Native-AOT-compatible)
dotnet add package CQRSharp.EntityFrameworkCore   # EF Core (relational) outbox + idempotency stores

Quick Start

Register CQRSharp on your host. AddCqrsGenerated is emitted by the source generator and wires up every discovered handler:

services.AddCqrsGenerated();

Define a command and its handler:

public sealed class CreateUser : CommandBase
{
    public required string Name { get; init; }
}

public sealed class CreateUserHandler : ICommandHandler<CreateUser>
{
    public Task<CommandResult> Handle(CreateUser command, CancellationToken ct)
        => Task.FromResult(CommandResult.FromSuccess());
}

Dispatch it through the single injected façade, ICqrsDispatcher:

public sealed class UsersController(ICqrsDispatcher dispatcher)
{
    public Task Create(string name)
        => dispatcher.Send(new CreateUser { Name = name });
}

Queries derive from QueryBase<TResult> and are handled by IQueryHandler<TQuery, TResult>; streaming requests are dispatched with dispatcher.Stream, and notifications implement INotification and are published with dispatcher.Publish. Use CommandBase<TContext> / QueryBase<TResult, TContext> when a request needs a custom context.

Order-insensitive wiring

Cross-cutting behaviors and stores are opt-in and can be composed in any order through the fluent overload of AddCqrsGenerated. The builder applies them in the correct sequence, so registration order never matters and a missing store is reported at startup rather than at first request:

services.AddCqrsGenerated(builder => builder
    .UseValidation()
    .UseInMemoryOutbox()   // dev/test; swap for AddRedisOutboxStore(...) or AddEntityFrameworkCoreOutboxStore<TContext>(...)
    .ValidateOnStart());

For durable persistence, register a store from an integration package — AddRedisOutboxStore / AddRedisIdempotencyStore, or AddEntityFrameworkCoreOutboxStore<TContext> / AddEntityFrameworkCoreIdempotencyStore<TContext>.


Contributing

Contributions are welcome! Please open issues and pull requests for bug fixes, enhancements, or new features.

To contribute:

  1. Fork the repository.
  2. Create a new branch.
  3. Make your changes.
  4. Submit a pull request.

Please ensure that your code follows the project's coding standards and includes appropriate tests.


License

This project is licensed under the MIT License.


Note: This project is in active development.

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 is compatible.  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 is compatible.  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 (4)

Showing the top 4 NuGet packages that depend on CQRSharp.Core:

Package Downloads
CQRSharp

A lightweight, attribute-driven CQRS framework for .NET 8/9/10 with first-class Native AOT support. A Roslyn source generator wires up command, query, stream, and notification dispatch at compile time — no runtime reflection — and bundled analyzers catch wiring mistakes as you type. Install this meta-package for the full plug-and-play setup: abstractions, runtime, source generator, and analyzers.

CQRSharp.Pipelines

Optional, opt-in pipeline behaviors for CQRSharp — validation, unit of work, resilience/retries, timeouts, rate limiting, idempotency, and logging — plus a one-call pipeline-pack registration for sensible defaults.

CQRSharp.Redis

A 100% Native-AOT-clean Redis integration for CQRSharp. Its first feature is a durable IOutboxStore that persists outbox messages as discrete Redis hash fields (binary payloads stored verbatim) and runs all claim, lease, and finalize logic as atomic server-side Lua, so two processors never claim the same message and crashed claimants are reclaimed after a visibility timeout. It also provides a durable IIdempotencyStore that rejects duplicate requests via atomic set-if-not-exists claims with a server-side expiry window.

CQRSharp.EntityFrameworkCore

An Entity Framework Core integration for CQRSharp. Its first feature is a durable IOutboxStore backed by a DbContext: atomic claim with an optimistic-concurrency visibility lease, persisted retry/back-off and dead-lettering. It also provides a durable IIdempotencyStore backed by a keyed table with an optimistic-concurrency claim and a retention window. EF Core uses runtime query compilation, so this package is not Native-AOT or full-trim compatible.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.2.1 329 7/1/2026
4.2.0 173 6/30/2026
4.1.0 175 6/30/2026
4.0.3 177 6/30/2026
4.0.2 173 6/30/2026
4.0.1 175 6/30/2026
4.0.0 173 6/30/2026
3.1.0 134 6/26/2026

Version 3.1.0. Adds in-memory outbox and idempotency stores, a fail-fast startup validator, an order-insensitive fluent builder, and a unified TimeProvider clock seam.