CommandQuery.Framing 1.0.8

dotnet add package CommandQuery.Framing --version 1.0.8
NuGet\Install-Package CommandQuery.Framing -Version 1.0.8
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.Framing" Version="1.0.8" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CommandQuery.Framing --version 1.0.8
#r "nuget: CommandQuery.Framing, 1.0.8"
#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 CommandQuery.Framing as a Cake Addin
#addin nuget:?package=CommandQuery.Framing&version=1.0.8

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

Command Query Framework

Breaking changes for version 1.0.4 and higher

Objects

Commands
  • IBroker
  • Broker
  • IRqstMessage
  • IHandler
  • IAsyncHandler
Domain Event
  • IDomainEvent
  • IDomainEventPublisher
Static Response
  • Response

Setup

public void ConfigureServices(IServiceCollection services)
{
    /// this will add required interface
    /// this will also search your assemblies for
    /// types that can be handled
    services
        .AddCommandQuery(<Your assemblies here>);
}

Calling a Command or Query

Inject the IBroker into your class Call

public class TestController:Controller
{
	private ICommandBroker _broker;

	public TestController(IBroker broker)
	{
		_broker = broker;
	}

    [Route("/widget")]
    [HttpPost]
    public asycn Task<IActionResult> CreateWidget(Widget request)
    {
        // execute command
        var result = await _broker.HandleAsync<Widget, CommandResponse<string>>(request);

        //check command result
        if(result.Success)
        {
            // return success
            return Ok(result.Data);
        }

        // throw on failure
        throw new BadRequestException(result.Message, result.Exception);
    }
}

Creating a Command Handler

  • A Handler is used for gettting, inserting, updating, or deleting data from your database.
  • The DomainEventPublisher is used to publish messages accross your domain.
  • Ideally commands should be encapsulated and should not call other commands.
  • If you need to query for data then it should be part of the command encapsulating the functionality.
    public class CreateWidget : IAsyncHandler<CreateWidgetMessage, CommandResponse<string>>
    {
        private readonly IDomainEventPublisher _publisher;

        public CreateWidget(IDomainEventPublisher publisher)
        {
            _publisher = publisher;
        }
        public async Task<CommandResponse<string>> Execute(CreateWidgetMessage message)
        {
            var response = Guid.NewGuid().ToString();

            _publisher.MessageResult += (sender, eventargs) =>
                                        {
                                            response += $" message was sent and processed with Success={eventargs.Success}";
                                        };

            await _publisher.Publish(new WidgetCreated());

            return Response.Ok(response);
        }
    }

⇐ 1.0.3

Objects

ICommandHandler CommandHandler IAsyncCommandHandler AsyncCommandHandler ICommandBroker CommandBroker IQueryHandler QueryHandler IAsyncQueryHandler AsyncQueryHandler IDomainEventPublisher DomainEventPublisher ICommandBroker CommandBroker CommandResponse IDomainEvent

Basic Setup

  • Register the CommandBroker
  • Register the DomainEventPublisher
  • Define and Register the CommandHandlers
  • Define and Register the QueryHandlers
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ICommandBroker, CommandBroker>();
    service.AddTransient<IDomainEventPublisher, DomainEventPublisher>();
    service.AddTransient<ICommandHandler<CreateMessage,CommandResponse>, CreateNewWidgetCommand>();
    service.AddTransient<IQueryHandler<GetWidget,Widget>, GetWidgetQuery>();
}

Calling a Command or Query

Inject the ICommandBroker into your class Call

public class TestController:Controller
{
	private ICommandBroker _commandBroker;

	public TestController(ICommandBroker commandBroker)
	{
		_commandBroker = commandBroker;
	}

    [Route("/widget")]
    [HttpPost]
    public asycn Task<IActionResult> CreateWidget(Widget request)
    {
        // execute command
        var result = await _commandBroker.ExecuteAsync<Widget, CommandResponse>(request);

        //check command result
        if(result.Result == CommandStatus.Success)
        {
            // return success
            return Ok();
        }

        // throw on failure
        throw new BadRequestException(result.Message, result.Exception);
    }
}

Creating a Command Handler

Command Handler is used for inserting, updating, or deleting data from your database. The DomainEventPublisher is used to publish an outbound message for your domain or the message could be sent to a message queue. Ideally commands should be encapsulated and should not call other commands or queries. If you need to query for data then it should be part of the command encapsulating the functionality.

public class WidgetCommand : AsyncCommandHandler<CreateNewWidgetMessage,CommandResponse>
{
    public WidgetCommand(IDomainEventPublisher) : base(domainEventPublisher)

    public override async Task<CommandResponse> Execute(CreateNewWidgetMessage createNewWidgetMessage)
    {
        //do your work here

        //publish your message accross the domain
        DomainEventPublisher.Publish(new MessageHere());

        return CommandResponse.Okay();
    }
}

Create a Query Handler

Query Handler is used for fetching data from your data source and returning a projection.

public class GetWidgetDataQuery:IAsyncQueryHandler<GetWidgetDataRequest, WidgetModel>
{
    public async Task<WidgetModel> Execute(GetWidgetDataRequest message)
    {
        //query for your data here
        //do some work

        return result;
    }
}
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 211 11/16/2023
1.0.7 668 9/12/2022
1.0.6 530 1/19/2022
1.0.5 495 8/5/2021
1.0.3 1,408 2/25/2021
1.0.2 1,216 7/8/2020
1.0.1 1,249 4/13/2020
1.0.0 2,685 11/21/2018