Event Sourcing and CQRS are friends
What will we cover
- Who the hell is this guy.
- A quick introduction.
- What are bottom up estimates.
- Quick demo of what I am building.
- Third Party Service and Libraries.
- Programming patterns I am using.
Aaron
Gravypower
- https://blog.gravypower.net
- @gravypower
- https://github.com/gravypower
Command Query Responsibility Segregation (CQRS)
Steven van Deursen
AKA .NET Junkie
Command Query Responsibility Segregation (CQRS)
Where?
Asking a question should not change the answer.
Bertrand Meyer
Meyer, Bertrand. "Eiffel: a language for software engineering" (PDF). p. 22. Retrieved 16 December 2014.
Bertrand Meyer first introduced the idea as a part of of his work on the Eiffel programming language.
https://en.wikipedia.org/wiki/Command–query_separation
Command Query Responsibility Segregation (CQRS)
What?
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
var command = new ChangeChannel
{
ChannelId = channelId
};
public class ChangeChannelCommandHandler
{
private readonly TV _tv;
public ChangeChannelCommandHandler(TV tv)
{
_tv = tv;
}
public void Handle(ChangeChannelCommand command)
{
// Change the Channel
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class TvController
{
private readonly ChangeChannelCommandHandler handler;
public TvController(ChangeChannelCommandHandler handler)
{
this.handler = handler;
}
public void ChangeChannel(int channelId)
{
var command = new ChangeChannelCommand
{
ChannelId = channelId,
};
this.handler.Handle(command);
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
var query = new GetChannelQuery();
public class GetChannelQueryHandler
{
private readonly TV _tv;
public GetChannelQueryHandler(TV tv)
{
_tv = tv;
}
public int Handle(GetChannelQuery query)
{
return _tv.Channel;
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class TvController
{
private readonly ChangeChannelCommandHandler _changeChannelCommandHandler;
private readonly GetChannelQueryHandler _getChannelQueryHandler;
public TvController(
MoveCustomerCommandHandler changeChannelCommandHandler,
GetChannelQueryHandler getChannelQueryHandler)
{
_changeChannelCommandHandler = changeChannelCommandHandler;
_getChannelQueryHandler = getChannelQueryHandler;
}
public void ChangeChannel(int channelId)
{
...
}
public int GetChannel()
{
var query = new GetChannelQuery();
return _getChannelQueryHandler.Handle(query);
}
}
Command Query Responsibility Segregation (CQRS)
So what Aaron, why should I care about this pattern?
Single Responsibility
SOLID principles
- Single Responsibility
- Open Closed
- Liskov Substitution
- Interface Segregation
- Dependency Inversion
Command Query Responsibility Segregation (CQRS)
So what Aaron, why should I care about this pattern?
Boundaries that you can decorate
Command Query Responsibility Segregation (CQRS)
So what Aaron, why should I care about this pattern?
Boundaries in an application give you and opportunity to add cross cutting concerns or targeted aspects to your logic
We can do this in CQRS by created interfaces for the command and query handlers, and use the decorator structural pattern.
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
Command Query Responsibility Segregation (CQRS)
So what Aaron, why should I care about this pattern?
public class ChangeChannelCommandHandler : ICommandHandler<ChangeChannelCommand>
{
private readonly TV _tv;
public ChangeChannelCommandHandler(TV tv)
{
_tv = tv;
}
public void Handle(ChangeChannelCommand command)
{
// Change the Channel
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class TvController
{
private readonly ICommandHandler<ChangeChannelCommand> _handler;
public TvController(ICommandHandler<ChangeChannelCommand> handler)
{
_handler = handler;
}
public void ChangeChannel(int channelId)
{
var command = new ChangeChannelCommand
{
ChannelId = channelId,
};
_handler.Handle(command);
}
public void GetChannel()
{
...
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class LivingRoom
{
private const int ABCKidsChannel = 24;
private readonly TvController _tvController;
public LivingRoom(TvController tvController)
{
_tvController = tvController;
}
public void EnterRoom()
{
if(_tvController.GetChannel() != ABCKidsChannel)
{
//Chnage the channel to ABC Kids
_tvController.ChangeChannel(ABCKidsChannel);
}
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class House
{
public LivingRoom LivingRoom;
public void LivingRoom()
{
var tv = new TV();
var changeChannelCommandHandler = new ChangeChannelCommandHandler(tv);
var tvController = new TvController(changeChannelCommandHandler);
LivingRoom = new LivingRoom(tvController);
LivingRoom.EnterRoom();
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class GuardFromChannelNineDecorator : ICommandHandler<ChangeChannelCommand>
{
private const int NineEntertainment Channel = 9;
private readonly ICommandHandler<TCommand> _decoratee
private readonly TV _tv;
public ChangeChannelCommandHandler(TV tv, ICommandHandler<ChangeChannelCommand> decoratee)
{
_tv = tv;
_decoratee = decoratee;
}
public void Handle(ChangeChannelCommand command)
{
if(command.ChannelId == NineEntertainment)
{
throw new System.InvalidOperationException("You can not watch Married at First Sight");
}
decoratee.Handle(command);
}
}
public class GuardFromChannelNineDecorator : ICommandHandler<ChangeChannelCommand>
{
private const int NineEntertainment Channel = 9;
private const int ABCKidsChannel = 24;
private readonly ICommandHandler<TCommand> _decoratee
private readonly TV _tv;
public ChangeChannelCommandHandler(TV tv, ICommandHandler<ChangeChannelCommand> decoratee)
{
_tv = tv;
_decoratee = decoratee;
}
public void Handle(ChangeChannelCommand command)
{
if(command.ChannelId == NineEntertainment)
{
command.ChannelId = ABCKidsChannel;
}
decoratee.Handle(command);
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class House
{
public LivingRoom LivingRoom;
public void LivingRoom()
{
var tv = new TV();
var changeChannelCommandHandler = new ChangeChannelCommandHandler(tv);
var guardFromChannelNineDecorator =
new GuardFromChannelNineDecorator(tv, changeChannelCommandHandler);
var tvController = new TvController(guardFromChannelNineDecorator);
LivingRoom = new LivingRoom(tvController);
LivingRoom.EnterRoom();
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
public class House
{
public LivingRoom LivingRoom;
public void LivingRoom()
{
var tv = new TV();
var changeChannelCommandHandler = new ChangeChannelCommandHandler(tv);
var turnTvOffAfterFiveAttemptsDecorator =
new TurnTvOffAfterFiveAttemptsDecorator(tv, changeChannelCommandHandler);
var guardFromChannelNineDecorator =
new GuardFromChannelNineDecorator(tv, turnTvOffAfterFiveAttemptsDecorator);
var tvController = new TvController(guardFromChannelNineDecorator);
LivingRoom = new LivingRoom(tvController);
LivingRoom.EnterRoom();
}
}
Command Query Responsibility Segregation (CQRS)
Just show me the code Aaron.
var container = new Container();
container.Register(
typeof(ICommandHandler<ChangeChannelCommand>),
typeof(ChangeChannelCommandHandler));
container.RegisterDecorator(
typeof(ICommandHandler<ChangeChannelCommand>),
typeof(TurnTvOffAfterFiveAttemptsDecorator));
container.RegisterDecorator(
typeof(ICommandHandler<ChangeChannelCommand>),
typeof(GuardFromChannelNineDecorator));
Note not all DI libraries are created equally, some may not support syntax like this.
Command Query Responsibility Segregation (CQRS)
Cross-Cutting Concerns
In aspect-oriented software development, cross-cutting concerns are aspects of a program that affect other concerns.
https://en.wikipedia.org/wiki/Cross-cutting_concern
Link to my Blog
Event Sourcing and CQRS are friends
By Aaron Job
Event Sourcing and CQRS are friends
- 310