CQRSharp.Redis
4.2.1
dotnet add package CQRSharp.Redis --version 4.2.1
NuGet\Install-Package CQRSharp.Redis -Version 4.2.1
<PackageReference Include="CQRSharp.Redis" Version="4.2.1" />
<PackageVersion Include="CQRSharp.Redis" Version="4.2.1" />
<PackageReference Include="CQRSharp.Redis" />
paket add CQRSharp.Redis --version 4.2.1
#r "nuget: CQRSharp.Redis, 4.2.1"
#:package CQRSharp.Redis@4.2.1
#addin nuget:?package=CQRSharp.Redis&version=4.2.1
#tool nuget:?package=CQRSharp.Redis&version=4.2.1
CQRSharp
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, composed order-insensitively through the fluent
AddCqrsGenerated(b => ...)builder (UseValidation(),UseResilience(...),UseOutbox(...),UseIdempotency(...), …). - 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, or an
IIdempotentRequest/IRetryableRequestmarker whose behavior was never enabled) 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()
.UseOutbox(o => o.UseInMemoryStore()) // dev/test; swap the store for o.UseRedis(...) or o.UseEntityFrameworkCore<TContext>()
.ValidateOnStart());
The outbox and idempotency are each enabled in one cohesive step that selects the mode and registers the store, e.g.
UseOutbox(o => o.Transactional().UseEntityFrameworkCore<MyDbContext>()) or UseIdempotency(i => i.UseRedis(connectionString)).
For durable persistence, add the integration package for your backing store (CQRSharp.Redis or
CQRSharp.EntityFrameworkCore) and choose its store verb inside UseOutbox / UseIdempotency.
Contributing
Contributions are welcome! Please open issues and pull requests for bug fixes, enhancements, or new features.
To contribute:
- Fork the repository.
- Create a new branch.
- Make your changes.
- 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 | 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 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. |
-
net10.0
- CQRSharp.Abstractions (>= 4.2.1)
- CQRSharp.Core (>= 4.2.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.2)
- Microsoft.Extensions.Options (>= 9.0.2)
- StackExchange.Redis (>= 2.8.16)
-
net8.0
- CQRSharp.Abstractions (>= 4.2.1)
- CQRSharp.Core (>= 4.2.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.2)
- Microsoft.Extensions.Options (>= 9.0.2)
- StackExchange.Redis (>= 2.8.16)
-
net9.0
- CQRSharp.Abstractions (>= 4.2.1)
- CQRSharp.Core (>= 4.2.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.2)
- Microsoft.Extensions.Options (>= 9.0.2)
- StackExchange.Redis (>= 2.8.16)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version 4.2.1. No functional changes in this package.