CommandQuery 2.0.0

.NET Standard 2.0
dotnet add package CommandQuery --version 2.0.0
NuGet\Install-Package CommandQuery -Version 2.0.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="CommandQuery" Version="2.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CommandQuery --version 2.0.0
#r "nuget: CommandQuery, 2.0.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install CommandQuery as a Cake Addin
#addin nuget:?package=CommandQuery&version=2.0.0

// Install CommandQuery as a Cake Tool
#tool nuget:?package=CommandQuery&version=2.0.0

CommandQuery ⚙️

build CodeFactor

Command Query Separation for .NET

Commands

Commands change the state of a system but [traditionally] do not return a value. They write (create, update, delete) data.

Commands implement the marker interface ICommand and command handlers implement ICommandHandler<in TCommand>.

public class FooCommand : ICommand
{
    public string Value { get; set; }
}

public class FooCommandHandler : ICommandHandler<FooCommand>
{
    private readonly ICultureService _cultureService;

    public FooCommandHandler(ICultureService cultureService)
    {
        _cultureService = cultureService;
    }

    public async Task HandleAsync(FooCommand command, CancellationToken cancellationToken)
    {
        if (command.Value == null) throw new FooCommandException("Value cannot be null", 1337, "Try setting the value to 'en-US'");

        _cultureService.SetCurrentCulture(command.Value);

        await Task.CompletedTask;
    }
}

Commands can also return a result.

public class BazCommand : ICommand<Baz>
{
    public string Value { get; set; }
}

public class Baz
{
    public bool Success { get; set; }
}

public class BazCommandHandler : ICommandHandler<BazCommand, Baz>
{
    private readonly ICultureService _cultureService;

    public BazCommandHandler(ICultureService cultureService)
    {
        _cultureService = cultureService;
    }

    public async Task<Baz> HandleAsync(BazCommand command, CancellationToken cancellationToken)
    {
        var result = new Baz();

        try
        {
            _cultureService.SetCurrentCulture(command.Value);

            result.Success = true;
        }
        catch
        {
            // TODO: log
        }

        return await Task.FromResult(result);
    }
}

Commands with result implement the marker interface ICommand<TResult> and command handlers implement ICommandHandler<in TCommand, TResult>.

Queries

Queries return a result and do not change the observable state of the system (are free of side effects). They read and return data.

Queries implement the marker interface IQuery<TResult> and query handlers implement IQueryHandler<in TQuery, TResult>.

public class BarQuery : IQuery<Bar>
{
    public int Id { get; set; }
}

public class Bar
{
    public int Id { get; set; }

    public string Value { get; set; }
}

public class BarQueryHandler : IQueryHandler<BarQuery, Bar>
{
    private readonly IDateTimeProxy _dateTime;

    public BarQueryHandler(IDateTimeProxy dateTime)
    {
        _dateTime = dateTime;
    }

    public async Task<Bar> HandleAsync(BarQuery query, CancellationToken cancellationToken)
    {
        var result = new Bar { Id = query.Id, Value = _dateTime.Now.ToString("F") };

        return await Task.FromResult(result);
    }
}
Samples
Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (9)

Showing the top 5 NuGet packages that depend on CommandQuery:

Package Downloads
CommandQuery.AspNetCore

Command Query Separation for ASP.NET Core 🌐 ✔️ Provides generic actions for handling the execution of commands and queries ✔️ Enables APIs based on HTTP POST and GET 📄 https://hlaueriksson.me/CommandQuery.AspNetCore/

CommandQuery.AzureFunctions

Command Query Separation for Azure Functions ⚡ ✔️ Provides generic function support for commands and queries with HTTPTriggers ✔️ Enables APIs based on HTTP POST and GET 📄 https://hlaueriksson.me/CommandQuery.AzureFunctions/

CommandQuery.AWSLambda

Command Query Separation for AWS Lambda ⚡ ✔️ Provides generic function support for commands and queries with Amazon API Gateway ✔️ Enables APIs based on HTTP POST and GET 📄 https://hlaueriksson.me/CommandQuery.AWSLambda/

CommandQuery.AspNet.WebApi

Command Query Separation for ASP.NET Web API 2 🌐 ✔️ Provides generic actions for handling the execution of commands and queries ✔️ Enables APIs based on HTTP POST and GET 📄 https://hlaueriksson.me/CommandQuery.AspNet.WebApi/

CommandQuery.DependencyInjection

Dependency Injection for CommandQuery

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.0 971 7/29/2021
1.0.0 3,212 2/2/2020
0.9.0 2,276 11/20/2019
0.8.0 4,666 2/16/2019
0.7.0 1,551 9/22/2018
0.6.0 1,511 9/15/2018
0.5.0 1,518 7/6/2018
0.4.0 1,360 5/16/2018
0.3.2 1,451 5/1/2018
0.3.1 1,444 1/6/2018
0.3.0 1,417 1/3/2018
0.2.0 1,555 4/25/2017
0.1.1 1,317 8/29/2016
0.1.0 1,131 8/28/2016

- Removed target framework net461 🎯
- Renamed method ProcessWithResultAsync to ProcessAsync in CommandProcessor 💥
- Added CancellationToken parameter to ProcessAsync methods in CommandProcessor and QueryProcessor
- Renamed CommandTypeCollection to CommandTypeProvider 💥
- Renamed QueryTypeCollection to QueryTypeProvider 💥
- Added method AssertConfigurationIsValid to CommandProcessor and QueryProcessor
- CommandProcessor, CommandTypeProvider, QueryProcessor and QueryTypeProvider are now added to IServiceCollection as singletons
- CommandTypeException is now thrown if multiple commands with the same name is added to the CommandTypeProvider
- QueryTypeException is now thrown if multiple queries with the same name is added to the QueryTypeProvider