The document discusses CQRS (Command Query Responsibility Segregation), an architectural pattern that separates read and write operations into different models. It describes how CQRS can help simplify complex systems by separating commands, which change the system state, from queries that read the state. The key aspects of implementing CQRS are discussed, including using command and query handlers, a command dispatcher, and ensuring consistency between read and write models. The document advocates implementing CQRS yourself using simple interfaces and classes rather than a framework.
65. public interface IQuery<out TResult>
{
TResult Execute();
}
public class QueryDispatcher : IQueryDispatcher
{
TResult Run<out TResult>(IQuery<TResult> query)
{
using(var tx = session.OpenReadOnlyTransaction())
{
return query.Execute();
}
}
}
66. public interface IQuery<out TResult>
{
TResult Execute();
}
public class QueryDispatcher : IQueryDispatcher
{
TResult Run<out TResult>(IQuery<TResult> query)
{
using(var tx = session.OpenReadOnlyTransaction())
{
return query.Execute();
}
}
}
67. public interface ICommandHandler<in TCommand>
{
void Execute(TCommand command);
}
public class CommandDispatcher : ICommandDispatcher
{
public void Execute<in TCommand>(TCommand command)
{
var handler = ResolveCommandHandler<TCommand>();
handler.Execute(command);
}
}
68. public class TaskController
{
public TaskController(TaskManager taskManager) {…}
public ActionResult MarkAsFinalized(TaskId taskId)
{
taskManager.UpdateStatus(taskId, TaskStatuses.Finalized);
taskManager.UpdateFinalizationDate(taskId, DateTime.Now);
taskManager.UpdateFinalizedBy(taskId, CurrentUser.Id);
return Success;
}
}
69. public class TaskController : Controller
{
public TaskController(CommandDispatcher commandDispatcher) {…}
public ActionResult MarkAsFinalized(TaskId taskId)
{
var finalizeCommand = new FinalizeTaskCommand(taskId,
CurrrentUser.Id);
commandDispatcher.Execute(finalizeCommand);
return Success;
}
}
70. public class FinalizeTaskCommand
{
public FinalizeTaskCommand(TaskId id, UserId finalizingUser)
{…}
public TaskId Id { get; private set; }
public UserId FinalizingUser { get; private set; }
}
71. public class FinalizeTaskCommandHandler
: ICommandHandler<FinalizeTaskCommand>
{
public FinalizeTaskCommandHanlder(
ITaskRepository repository,
IDateTimeProvider dtp
) {…}
public void Execute(FinalizeTaskCommand command)
{
var task = repository.GetById(command.Id);
task.Status = TaskStatuses.Done;
task.FinalizedAt = dtp.Now();
task.FinalizedBy = command.FinalizingUser;
}
}
72. public class FinalizeTaskCommandHandler
: ICommandHandler<FinalizeTaskCommand>
{
public FinalizeTaskCommandHanlder(
ITaskRepository repository,
IDateTimeProvider dtp
) {…}
public void Execute(FinalizeTaskCommand command)
{
var task = repository.GetById(command.Id);
task.Finalize(dtp.Now(), command.FinalizingUser);
}
}