Commands, queries and event handlers.
Adds an ability to create and process commands in the sense of CQRS.
dotnet add package Convey.CQRS.Commands
Implement ICommand
(marker) interface in the selected class. Since the command represents the user’s intention you should follow the convention:
public class CreateAccount : ICommand
{
public Guid Id { get; }
public string Email { get; }
public string Password { get; }
public CreateUser(id, email, password)
{
Id = id;
Email = email;
Password = password;
}
}
Create dedicated command handler class that implements ICommandHandler<TCommand>
interface with HandleAsync()
method:
public class CreateAccountHandler : ICommandHandler<CreateAccount>
{
public Task HandleAsync(CreateAccount command)
{
//put the handling code here
}
}
You can easily register all command handlers in DI container by calling AddCommandHandlers()
method on IConveyBuilder
:
public IServiceProvider ConfigureServices(this IServiceCollection services)
{
var builder = services.AddConvey()
.AddCommandHandlers();
//other registrations
return builder.Build();
}
Dispatching a particular command object can be also done using Convey package. Start with registering in-memory dispatcher on your IConveyBuilder
by calling a AddInMemoryCommandDispatcher()
method:
public IServiceProvider ConfigureServices(this IServiceCollection services)
{
var builder = services.AddConvey()
.AddCommandHandlers()
.AddInMemoryCommandDispatcher();
//other registrations
return builder.Build();
}
Then simply inject ICommandDispatcher
into a class and call DispatchAsync()
method:
public class AccountsService
{
private readonly ICommandDispatcher _dispatcher;
public AccountsService(ICommandDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public Task CreateAccountAsync(CreateAccount command)
=> _dispatcher.DispatchAsync(command);
}
Adds an ability to create and process queries in the sense of CQRS.
dotnet add package Convey.CQRS.Queries
Implement IQuery<TResult>
interface in the selected class:
public class GetAccount : IQuery<AccountDto>
{
public Guid Id { get; set; }
}
Create dedicated query handler class that implements IQueryHandler<TQuery, TResult>
interface with HandleAsync()
method:
public class GetAccountHandler : IQueryHandler<GetAccount, AccountDto>
{
public Task<AccountDto> HandleAsync(GetAccount query)
{
//put the handling code here
}
}
You can easily register all query handlers in DI container by calling AddQueryHandlers()
method on IConveyBuilder
:
public IServiceProvider ConfigureServices(this IServiceCollection services)
{
var builder = services.AddConvey()
.AddQueryHandlers();
//other registrations
return builder.Build();
}
Dispatching a particular query object can be also done using Convey package. Start with registering in-memory dispatcher on your IConveyBuilder
by calling a AddInMemoryQueryDispatcher()
method:
public IServiceProvider ConfigureServices(this IServiceCollection services)
{
var builder = services.AddConvey()
.AddQueryHandlers()
.AddInMemoryQueryDispatcher();
//other registrations
return builder.Build();
}
Then simply inject IQueryDispatcher
into a class and call DispatchAsync()
method:
public class AccountsService
{
private readonly IQueryDispatcher _dispatcher;
public AccountsService(IQueryDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public Task<AccountDto> GetAccountAsync(Guid id)
=> _dispatcher.DispatchAsync(new GetAccount { Id = id });
}
Adds ability to create and process events in the sense of CQRS.
dotnet add package Convey.CQRS.Events
Implement IEvent
or IRejectedEvent
(marker) interface in the selected class. Since the event represents something that already happened, you should follow the convention:
public class AccountCreated : IEvent
{
public Guid Id { get; }
public AccountCreated(id)
{
Id = id;
}
}
Create dedicated event handler class that implements IEventHandler<TEvent>
interface with HandleAsync()
method:
public class AccountCreatedHandler : IEventHandler<AccountCreated>
{
public Task HandleAsync(AccountCreated @event)
{
//put the handling code here
}
}
You can easily register all event handlers in DI container by calling AddEventHandlers()
method on IConveyBuilder
:
public IServiceProvider ConfigureServices(this IServiceCollection services)
{
var builder = services.AddConvey()
.AddEventHandlers();
//other registrations
return builder.Build();
}
Dispatching a particular event object can be also done using Convey package. Start with registering in-memory dispatcher on your IConveyBuilder
by calling a AddInMemoryEventDispatcher()
method:
public IServiceProvider ConfigureServices(this IServiceCollection services)
{
services.AddOpenTracing();
var builder = services.AddConvey()
.AddCommandHandlers()
.AddInMemoryEventDispatcher();
//other registrations
return builder.Build();
}
Then simply inject IEventDispatcher
into a class and call DispatchAsync()
method:
public class AccountsService
{
private readonly IEventDispatcher _dispatcher;
public AccountsService(IEventDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public Task PostProcessAccountCreation(AccountCreated @event)
=> _dispatcher.DispatchAsync(@event);
}