VersionFlow.Extensions.Cqrs 1.0.1

dotnet add package VersionFlow.Extensions.Cqrs --version 1.0.1
                    
NuGet\Install-Package VersionFlow.Extensions.Cqrs -Version 1.0.1
                    
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="VersionFlow.Extensions.Cqrs" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="VersionFlow.Extensions.Cqrs" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="VersionFlow.Extensions.Cqrs" />
                    
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 VersionFlow.Extensions.Cqrs --version 1.0.1
                    
#r "nuget: VersionFlow.Extensions.Cqrs, 1.0.1"
                    
#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 VersionFlow.Extensions.Cqrs@1.0.1
                    
#: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=VersionFlow.Extensions.Cqrs&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=VersionFlow.Extensions.Cqrs&version=1.0.1
                    
Install as a Cake Tool

VersionFlow.Extensions.Cqrs

1.0.1 · .NET 10+ · MIT

A dependency-free pair of direct-call handler contracts. No registry, mediator, scanner, or DI dependency is required. Commands and queries use the same contracts; use names and application design to distinguish state changes from reads.

<PackageReference Include="VersionFlow.Extensions.Cqrs" Version="1.0.1" />

Plain CQRS

using VersionFlow.Extensions.Cqrs;

public sealed record GetPrice(int Quantity);
public sealed class GetPriceHandler : ICqrsHandler<GetPrice, decimal>
{
    public Task<decimal> HandleAsync(GetPrice request, CancellationToken ct = default)
    {
        ct.ThrowIfCancellationRequested();
        return Task.FromResult(request.Quantity * 10m);
    }
}

Call the concrete handler directly or register it with ordinary DI:

services.AddScoped<ICqrsHandler<GetPrice, decimal>, GetPriceHandler>();

With the separate DI extension, use [Service(typeof(ICqrsHandler<GetPrice, decimal>))] and AddAttributedServices instead. [Service] alone registers only the concrete class. Closed generic interfaces are valid for ordinary DI binding.

ICqrsHandler<TRequest> returns Task; ICqrsHandler<TRequest, TResponse> returns Task<TResponse>. Both accept an optional cancellation token. Validation, transactions, authorization, cancellation handling, and exception behavior belong to application code. Native DI requires the exact requested service registration; C# request contravariance does not create extra bindings.

Versioned CQRS with Core

Install VersionFlow.Core 1.0.1. Its generator requires a non-generic contract, so wrap the CQRS interface:

using VersionFlow;
using VersionFlow.Extensions.Cqrs;
using VersionFlow.Extensions.DI;

public interface IGetPriceHandler : ICqrsHandler<GetPrice, decimal> { }

[Service]
[Versioned(typeof(IGetPriceHandler), 1, Key = "Pricing")]
public sealed class GetPriceV1 : IGetPriceHandler
{
    public Task<decimal> HandleAsync(GetPrice request, CancellationToken ct = default)
        => Task.FromResult(request.Quantity * 10m);
}

[Service]
[Versioned(typeof(IGetPriceHandler), 2, Key = "Pricing")]
public sealed class GetPriceV2 : IGetPriceHandler
{
    public Task<decimal> HandleAsync(GetPrice request, CancellationToken ct = default)
        => Task.FromResult(request.Quantity * 9m);
}

The Service attribute above comes from the optional VersionFlow.Extensions.DI package. Startup for implementations in the application assembly:

builder.Services.AddAttributedServices();
builder.Services.AddVersionFlow(options => options.Classes["Pricing"] = "2");

Inject IGetPriceHandler and call HandleAsync normally. Core automatically links generated catalogs and registers the routing interface. Configuration can also come from AddVersionFlow(builder.Configuration.GetSection("VersionFlow")). No catalog or dispatcher call is needed for normal setup.

Do not pass typeof(ICqrsHandler<GetPrice, decimal>) directly to Versioned. Do not use Service interface binding/automatic discovery on the versioned implementations: the dispatcher owns IGetPriceHandler. The inherited HandleAsync method is supported and its configuration key is Pricing.HandleAsync. Directly injecting GetPriceV1 deliberately bypasses routing.

For a multi-project application, reference Core in startup and declaring projects, rebuild them for 1.0.1, and pass the implementation assemblies to AddAttributedServices. Referenced generated catalogs are discovered automatically; DI still needs concrete registrations and constructor dependencies. Core's README covers advanced manual setup and opt-out.

MIT. Copyright (c) 2026 Bradley Ables. Full license included as LICENSE.

Product Compatible and additional computed target framework versions.
.NET 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.
  • net10.0

    • No dependencies.

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.0.1 0 11/13/2026
1.0.0 0 11/13/2026