Pavas.Patterns.Cqrs 1.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package Pavas.Patterns.Cqrs --version 1.0.3                
NuGet\Install-Package Pavas.Patterns.Cqrs -Version 1.0.3                
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="Pavas.Patterns.Cqrs" Version="1.0.3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Pavas.Patterns.Cqrs --version 1.0.3                
#r "nuget: Pavas.Patterns.Cqrs, 1.0.3"                
#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.
// Install Pavas.Patterns.Cqrs as a Cake Addin
#addin nuget:?package=Pavas.Patterns.Cqrs&version=1.0.3

// Install Pavas.Patterns.Cqrs as a Cake Tool
#tool nuget:?package=Pavas.Patterns.Cqrs&version=1.0.3                

CQRS Design Pattern in .NET

Overview

The CQRS (Command Query Responsibility Segregation) pattern is a design pattern that separates the responsibilities of commands and queries in a system. Commands are used to modify the state, while queries are used to retrieve data. This separation leads to a more maintainable and scalable architecture.

Interfaces

Command Interfaces

  • ICommandDispatcher: Dispatches commands to their respective handlers.
  • ICommandHandler: Handles commands and optionally returns a result.
  • ICommandHandlerAsync: An asynchronous version of ICommandHandler.
public interface ICommandDispatcher
{
    Task<TValue> DispatchCommandAsync<TCommand, TValue>(TCommand command);
    Task DispatchCommandAsync<TCommand>(TCommand command);
    TValue DispatchCommand<TCommand, TValue>(TCommand command);
    void DispatchCommand<TCommand>(TCommand command);
}

public interface ICommandHandler<in TCommand>
{
    void Handle(TCommand command);
}

public interface ICommandHandler<in TCommand, out TResult>
{
    TResult Handle(TCommand command);
}

public interface ICommandHandlerAsync<in TCommand>
{
    Task HandleAsync(TCommand command, CancellationToken cancellationToken = new());
}

public interface ICommandHandlerAsync<in TCommand, TResult>
{
    Task<TResult> HandleAsync(TCommand command, CancellationToken cancellationToken = new());
}

Query Interfaces

  • IQueryDispatcher: Dispatches queries to their respective handlers.
  • IQueryHandler: Handles queries and returns a result.
  • IQueryHandlerAsync: An asynchronous version of IQueryHandler.
public interface IQueryDispatcher
{
    Task<TValue> DispatchQueryAsync<TQuery, TValue>(TQuery query);
    Task<TValue> DispatchQueryAsync<TValue>();
    TValue DispatchQuery<TQuery, TValue>(TQuery query);
    TValue DispatchQuery<TValue>();
}

public interface IQueryHandler<in TQuery, out TResult>
{
    TResult Handle(TQuery query);
}

public interface IQueryHandler<out TResult>
{
    TResult Handle();
}

public interface IQueryHandlerAsync<TResult>
{
    Task<TResult> HandleAsync(CancellationToken cancellationToken = new());
}

public interface IQueryHandlerAsync<in TQuery, TResult>
{
    Task<TResult> HandleAsync(TQuery query, CancellationToken cancellationToken = new());
}

Example Usage

Dispatching Queries

var queryDispatcher = serviceProvider.GetService<IQueryDispatcher>();

// Example async with query parameters 
var resultWithParams = await queryDispatcher.DispatchAsync<SomeQuery, SomeResult>(new SomeQuery());

// Example async without query parameters 
var resultWithoutParams = await queryDispatcher.DispatchAsync<SomeResult>()
    
// Example with query parameters
var resultWithParams = queryDispatcher.Dispatch<SomeQuery, SomeResult>(new SomeQuery());

// Example without query parameters
var resultWithoutParams = queryDispatcher.Dispatch<SomeResult>()

Dispatching Queries

var commandDispatcher = serviceProvider.GetService<ICommandDispatcher>();

// Example async with command response 
var resultWithParams = await commandDispatcher.DispatchAsync<SomeCommand, SomeResult>(new SomeCommand());

// Example async without command response 
await commandDispatcher.DispatchAsync<SomeCommand>(new SomeCommand())
    
// Example with command response
var resultWithParams = commandDispatcher.Dispatch<SomeCommand, SomeResult>(new SomeCommand());

// Example without command response
commandDispatcher.Dispatch<SomeCommand>(new SomeCommand())

Implementing Query Handlers

public class MyQueryHandler : IQueryHandlerAsync<SomeQuery, SomeResult>
{
    public async Task<SomeResult> HandleAsync(SomeQuery query, CancellationToken cancellationToken = new())
    {
        // Handle the query and return the result
    }
}

public class MyQueryHandler : IQueryHandler<SomeQuery, SomeResult>
{
    public SomeResult Handle(SomeQuery query)
    {
        // Handle the query and return the result
    }
}

Implementing Command Handlers

public class MyCommandHandler : ICommandHandlerAsync<SomeCommand, SomeResult>
{
    public async Task<SomeResult> HandleAsync(SomeCommand command, CancellationToken cancellationToken = new())
    {
        // Handle the command and return the result (if any)
    }
}

public class MyCommandHandler : ICommandHandler<SomeCommand, SomeResult>
{
    public SomeResult Handle(SomeCommand command)
    {
        // Handle the command and return the result (if any)
    }
}

Dependency Injection

var serviceCollection = new ServiceCollection();

// Register command handlers
serviceCollection.AddCommands();

// Register query handlers
serviceCollection.AddQueries();

var serviceProvider = serviceCollection.BuildServiceProvider();

Conclusion

The CQRS pattern provides a clear separation between commands and queries, making your application more maintainable and scalable. By implementing the interfaces and extension methods described above, you can easily integrate CQRS into your .NET applications.

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. 
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.0.8 82 9/23/2024
1.0.7 107 8/20/2024
1.0.6 98 8/20/2024
1.0.5 125 8/13/2024
1.0.4 113 8/12/2024
1.0.3 74 8/3/2024
1.0.2 79 8/3/2024
1.0.1 70 8/2/2024
1.0.0 83 8/2/2024