This project shows a clean way to use CQRS without using the MediatR library.
In C# is common to use a library named MediatR to implement CQRS. This is an amazing library but forces you to implement the interface INotification, INotificationHandler and IRequestHandler<T1,T2> in your domain/application layer coupling this with an infrastructure library. This is a different approach to avoid add this coupling.
public class CreateItemCommand : Command
{
public CreateItemCommand(Guid id, string name)
{
Id = id;
Name = name;
}
}
public class CreateItemCommandHandler : CommandHandler<CreateItemCommand>
{
private readonly ItemRepository _repository;
public CreateItemCommandHandler(ItemRepository repository)
{
_repository = repository;
}
public async Task Handle(CreateItemCommand command)
{
await _repository.Add(new Item(command.Id, command.Name));
}
}
public class FindItemQuery : Query
{
public Guid Id { get; private set; }
public FindItemQuery(Guid id)
{
Id = id;
}
}
public class FindItemQueryHandler : QueryHandler<FindItemQuery, ItemResponse>
{
private readonly ItemRepository _repository;
public FindItemQueryHandler(ItemRepository repository)
{
_repository = repository;
}
public async Task<ItemResponse> Handle(FindItemQuery query)
{
Item item = await _repository.GetById(query.Id);
return new ItemResponse(item.Id, item.Name, item.IsCompleted);
}
}
services.AddScoped<CommandHandler<CreateItemCommand>, CreateItemCommandHandler>();
services.AddScoped<QueryHandler<FindItemQuery, ItemResponse>, FindItemQueryHandler>();
services.AddCommandServices(typeof(Command).Assembly);
services.AddQueryServices(typeof(Query).Assembly);