Preface
This article is the first in a series of three articles. It's sole purpose is to 
introduce you to domain events and commands. The next article will show how, 
with almost no effort (thanks to Griffin.Decoupled) you can get started with the 
command/event type of applications. The series will end with an article showing 
how you can use the DDD domain model together with the command and event 
handling.
Introduction
When we start our profession as developers we complete applications very quickly. 
We giggle a bit for ourselves and look at the older programmers which finish 
just half of the application in the same amount of time. Our applications look 
good and work great. But in fact they are just lipstick on a pig:
![lipstickpig.jpeg]()
The problems don't surface until you have to start maintaining the application. 
You change the code in one place and suddenly a new bug appears in another. This 
is one of the most common problems when developing applications. The problem is 
really that you have high coupling between your classes. It might be because of 
leaky abstractions or violated layer boundaries. It's a menace.
![Red-Menace.jpg]()
Another typical problem is that we have to hard-code the application flow as a 
fixed sequence:
public
void Register(email, 
string userName, string word) 
{
    // 1. create
    var user = _repository.Create(email, userName, 
word);
     
    // 2. notify user
    var email = new 
MailMessage("[email protected]", 
email, "Account created",
"Welcome DUUUDE!");
    var client = new SmtpClient(); 
//configured in app.config
    client.Send(email);
     
    // 3. Notify admin
    var email = new 
MailMessage("[email protected]",
"[email protected]",
"Account created",
"User registered");
    client.Send(email);
}
Which will force us to make changes that will affect the entire sequence.
Consider the following: after a period of time you get a new requirement: The 
customer wants to audit all new users. To be able to do that we have to modify 
that code above. Changing the code breaks the Open/Closed principle (one of the 
SOLID ones). Why is that? Because every code change is a potential new bug. No 
modifications also means that we do not have to test it either. No changes = No 
new bugs (a bit simplified, but anyhow...).
To avoid changes we need some way to act upon actions/events.
Enter domain events
Domain events are one of the answers to our prayers.
![250px-The_Event_2010_Intertitle.svg.png]()
Domain events are a concept which I've borrowed (shamelessly stolen) from domain 
driven design. A domain event is a change (which is most often) driven by a 
user. It can be upon user login, when an administrator locks a user account or 
when a user posts a new forum reply.
Events are named like UserRegistered, ReplyPosted or OrderPayed. Events should 
be defined in a way that the average client would understand. An event named 
OrderUpdated is far to broad and doesn't really say anything (compared with 
OrderPayed, ItemAddedToOrder or OrderPaymentMethodChanged).
As you've might have figured out the domain events should always be named in 
past tense (it's just part of the best practice). Let's define a small event:
public
class ReplyPosted 
: DomainEventBase
{
    public ReplyPosted(string 
threadId, int postedById,
string comment)
    {
        ThreadId = threadId;
        PostedById = postedById;
        Comment = comment;
    } 
    public string 
ThreadId { get; private
set; }
    public string 
PostedById { get; 
private set; }
    public string 
Comment { get; private
set; }
}
Notice that we always use IDs instead of entities/objects in the domain events. 
We also keep the number of properties at a minimum. Only include information 
which is important to identify the entities in question and the information that 
describes the change in the system.
Keeping the events lightweight makes them less likely to change in the future. 
Trust me, you do not want to have to change all your event subscribers when your 
application has grown. Compare the ReplyPosted event with an OrderUpdated event 
and the amount of information that it would have had to contain (and the amount 
of logic that all subscribers would have had to have).
Let's examine how the previous code snippet would look like when we are using 
domain events:
public
void Register(email, 
string userName, string word)
{
    var user = _repository.Create(email, userName, word); 
    // publish the event, the 
method is implementation specific
    DomainEvent.Publish(new 
UserRegistered(user.Id));
}
The event is simple enough; see:
public
class UserRegistered 
: DomainEventBase
{
    public UserRegistered(int 
userId)
    {
        if (userId < 1) 
throw new 
ArgumentOutOfRangeException("userId", 
userId, "Specify a valid user id"); 
        UserId = userId;
    } 
    public int 
UserId { get; private
set; }
}
Our event is lean enough and will be published for us. Now we only need to act 
upon that event. That's done with the help of subscribers. Let's create two (to 
handle the code in the original method).
public
class 
WelcomeEmailSender : ISubscribeOn<UserRegistered> 
//read it as "I Subscribe On 
UserRegistered"
{
    public void 
Handle(UserRegistered domainEvent)
    {
        var email = new 
MailMessage("[email protected]", 
email, "Account created",
"Welcome DUUUDE!");
        var client = 
new SmtpClient(); 
//configured in app.config
        client.Send(email);
    }
} 
public
class 
UserRegisteredEmailSender : ISubscribeOn<UserRegistered>
{
    public void 
Handle(UserRegistered domainEvent)
    {
        var email = new 
MailMessage("[email protected]",
"[email protected]",
"Account created",
"User registered");
        var client = 
new SmtpClient(); 
//configured in app.config
        client.Send(email);
    }
}
You should always create a new class for every handler. It keeps them 
lightweight and easier to read/maintain. If you are using an IoC container you 
can also inject dependencies into them.
Let's also add support for the new client requirement: To be able to audit new 
users.
public
class AuditNewUsers 
: ISubscribeOn<UserRegistered>
{
    IForbiddenWordsRepository _repository;
    IUserRepository _userRepository; 
    public 
AuditNewUsers(IForbiddenWordsRepository repository, IUserRepository 
userRepository)
    {
        _repository = repository;
        _userRepository = userRepository;
    } 
    public void 
Handle(UserRegistered domainEvent)
    {
        var user = 
userRepository.Get(domainEvent.UserId);
        if (_repository.Exists(user.UserName))
        {
            var email = 
new MailMessage("[email protected]",
"[email protected]",
"Action required",
"You might want to inspect user #" + user.Id);
            var client =
new SmtpClient(); 
//configured in app.config
            client.Send(email);
        }
    }
}
As you see we only had to create a new event.
![no-code-harmed-300x155.png]()
I hope that you've got the grasp of domain events and how they help you to write 
more decoupled applications.
Command me, sire!
With the introduction of domain events we've got smaller classes which is more 
SOLID. It also means that we've captured the essence of what the user intended 
to do (the use case) by moving out all non-essential actions to event handlers. 
That's a good start. But we can decouple our architecture even further.
![Commandoposter.jpg]()
A traditional layered application looks like this (may or may not be using 
multiple tiers):
![cdraw.png]()
That design is great since it's very easy to follow what happens and when. The 
problem is that the service classes tend to get fat and changed often. And as 
you might know by now, every change of existing code is a potential bug. The 
solution for this is to retire those service classes and instead introduce 
commands.
Task based UIs vs CRUD UIs
But before we get into commands we'll have a prerequisite that we have to 
fulfill: Our UIs must be task based.
A typical CRUD based UI looks something like this:
![mqI60.png]()
CRUD applications are often data-centric. That is, our application is modeled 
from the database perspective. We just create UIs to allow the user to edit 
everything. The problem with that is that there is not really a way to validate 
that the correct combination of fields are properly validated.
Task-based applications are user-centric. The tasks are not something that you 
make up by yourself but something which is defined by your client. They most 
often correspond to a use case/story.
The corresponding task based UI looks like:
![hfQQh.png]()
The change is really that we define a set of actions that the user can take. 
Each of these actions are defined by your client. Your client probably doesn't 
say "I want to be able to edit all fields" but more likely "I want to 
be able to assign a case to a user". So you have a task named 
AssignCaseToUser. That my dear ladies and gentleman is a command.
With this approach it's much easier to validate the information since we have a 
specific action. For instance, it doesn't make sense to change the title when 
assigning a task. So we can exclude that field from the action. Also, we know 
that we should always update the AssignedAt field. Hence we do not expose that 
field but just update it our-self.
What is a command?
A command is a use case, not a database operation or something technical. The 
command is what the user (your client) wants to achieve. That also means that 
you should not try to write/design commands for reuse. That will come back and 
haunt you every night. Design a command to do what the user wants. Nothing more 
and nothing less.
RegisterUser, AssignTask, LockForum are use case driven commands while 
UpdateUserTable is more of an operation (and should really be part of a 
command).
This distinction is important if we want to be able to re-factor or scale our 
systems. The distinction makes our commands agnostic of the actual 
implementation.
Commands are always in a valid state
A command should always make sure that it's information is valid. You've 
probably seen commands that look like this:
public
class 
DelegateTask
{
    public int 
TaskId { get; set; 
}
    public int 
UserId { get; set; 
}
}
The problem with that is that the command will fail if one of the fields are not 
specified. Always validate the information when it's assigned, not later.
We should use the following convention:
- Mandatory fields should be specified in the constructor, the setters should be private.
- Optional fields should have get/set, but the setters should validate the contents
Command validation vs UI validation
Command validation does not replace view model validation or similar. The 
command validation is used to increase the chance of success when the command is 
actually executed while the UI validation is used to ensure that the user 
entered all information correctly (and instantly provide the user feedback).
The difference is subtle but important. When you enter information into the 
command you've probably already validated it once.
The UI validation might be done by a different team/developer than the command 
validation (or by the same developer but in different time periods). It's 
therefore important that the validation is made in both places so that we catch 
any changes early (instead of getting failing commands).
Commands do not return anything
Commands should not return anything. EVER!.
This is probably the hardest thing with commands to get accustomed to. Today we 
are so accustomed to giving the user feedback directly. And that isn't really 
possible with commands since they will be executed in the future (and not 
directly).
![cdraw (1).png]()
Here is a solution for most common problems:
Need to act upon the generated ID
Switch to GUIDs
GUIDs provide the worst performance when looking up information in the database. 
But they are implementation agnostic and can safely be generated by the code.
There are however GUIDs (not really GUIDs if we should be anal, but similar 
enough) that provides you better performance. Google "sequential GUIDs". Many 
database engines have similar GUIDs.
Act upon the generated domain event instead
We have our domain events now, right? Use them to handle additional processing 
if possible.
Need to present the result to the user
- Trick the user
 
 You have all the information already. Just update the UI with it. For instance stackoverflow.com uses this approach. The command will most likely have been processed by our system when the user updates the page.
 
- Distract the user
 
 Show the user a "Thank you so bloody much for the extra work, we'll save it into our systems !ASAP". (Being a developer you'll know that we meant "not As Soon As Possible", but the user will think that we've mistyped. That's what I call a win-win situation).
That page/message will provide our system a 
chance to process the command before the user does something else.
- Command vs handler
 
 In my own implementation I've decided to split the command request from it's processing. The command classes are in a strict sense just DTOs. They are used to carry the information to the actual handler. I find this acceptable since the command dispatcher will throw an exception if there are no handlers. (The distributed version will generate errors when the host can't find a handler.)
 
- Commands vs services
 
 Let's compare commands to the services. Services are most often just facades for root aggregates (Order, User etc). The services will therefore most often be much larger than the corresponding commands, which in turn reduce readability (it's not as easy to get a grip over what a services does). A command is more re-factor friendly since we can move sub actions into own methods (usually avoided in services since it's hard to tell what each method is used by). The service is also more prone to bugs since it wraps all operations for a root aggregate (and it's children). Changing one method may affect another one (and therefore also affect all usages).
 
 MvcController (or whatever you're using) will likely use one or more services. If we are using services in a controller then we have obtained the dependencies of all the service classes. Any change in the service can affect one or more of the controller methods. If we are using commands, each controller method has a dependency on a single command. Hence changing the command handler will only affect a single controller method.
The code
The customer has moved to a new place. Thus we need to change the delivery 
address:
public
class 
ChangeDeliveryAddress
{
    public ChangeDeliveryAddress(int 
userId, string street, 
string zipCode, string city)
    {
        if (userId < 1) 
throw new 
ArgumentOutOfRangeException("userId", 
userId, "Specify a valid user id");
        if (string.IsNullOrEmpty(street))
            throw new
ArgumentException("street",
"Street must be specified");
        if (string.IsNullOrEmpty(zipCode))
            throw new
ArgumentException("zipCode",
"ZipCode must be specified");
        if (string.IsNullOrEmpty(city))
            throw new
ArgumentException("city",
"City must be specified"); 
        //assignment here
    } 
    public string 
UserId { get; private
set; }
    public string 
Street { get; private
set; }
    public string 
ZipCode { get; private
set; }
    public string 
City { get; private
set; } 
    // State may be null
    public
string State
    {
        get;
        set;
    }
}
That was only the command request. We also need something that handles the 
command.
public
class 
ChangeDeliveryAddressHandler : IHandleCommand<ChangeDeliveryAddress>
//"I Handle Command 
ChangeDeliveryAddress"
{
    IUserRepository _repository; 
    public 
ChangeDeliveryAddressHandler(IUserRepository repository)
    {
        _repository = repository;
    } 
    public void 
Invoke(ChangeDeliveryAddress command)
    {
        var user = _repository.Get(command.UserId);
        user.ZipCode = command.zipCode;
        // [...] 
        DomainEvent.Publish(new 
DeliveryAddressChanged(user.Id, /* and all changed 
fields */));
    }
}
Do note that the command in this case is just a data source wrapper. That may 
not be in the future. The important thing today is that the event is generated 
and we can therefore act upon the command in a decoupled way.
What belongs in the command?
Now that we have obtained the domain events and commands there is still an issue 
to address. And that is, what belongs in the command or in the domain event 
handler.
The answer is that it's quite easy to solve. Ask your client. For instance: 
"Should we abort the user registration if the welcome email can't be sent? Or is 
it enough if we notify your support department so that they can contact the new 
user?".
Everything which is not fatal in a usecase / userstory should be placed in 
domain event handlers.
Handling customer feedback
We'll have to have a new way to interact with the users, since we should treat 
all commands as some asynchronous handlers which won't give us a result back. 
The easiest way to do that is to introduce a notification system. Simply create 
a new database table where all notifications are stored. Read it every time a 
new page is displayed.
The notification system should of course be a command and a domain event too. If 
you're writing a native client you can simply subscribe to the 
NotificationCreated event to be able to display it to the user.
Let me entertain you
To entertain you a bit, here is a command handler of mine (from my upcoming web 
startup). It subscribes to some domain events to capture the entire task 
delegation flow in the same place.
Look at the subscribed events and think of when they happen. When you get it 
you'll understand that the logic handles several different application flows. So 
it's more complex than it looks .
(Note that the domain events are published from within the domain models since I 
try to follow Domain Driven Design.)
public
class 
RequestTaskDelegationHandler :
IHandleCommand<RequestTaskDelegation>,
ISubscribeOn<InvitationAccepted>,
ISubscribeOn<FriendRequestAccepted>,
ISubscribeOn<FriendRequestRejected>
{
    private readonly 
ITodoItemStorage _todoItemStorage;
    private readonly 
IUserStorage _userStorage;
    private readonly 
IFriendDataStore _friendDataStore;
    private readonly 
ICommandDispatcher _commandDispatcher; 
    public 
RequestTaskDelegationHandler(ITodoItemStorage todoItemStorage, IUserStorage 
userStorage, IFriendDataStore friendDataStore, ICommandDispatcher 
commandDispatcher)
    {
        _todoItemStorage = todoItemStorage;
        _userStorage = userStorage;
        _friendDataStore = friendDataStore;
        _commandDispatcher = commandDispatcher;
    } 
    public void 
Invoke(RequestTaskDelegation command)
    {
        var item = _todoItemStorage.Load(command.TaskId);
        var delegatedBy = _userStorage.Load(command.DelegatedFromUserId);
        var delegateTo = 
command.DelegateTo.Contains("@") 
//userIds do not contain @
        ? _userStorage.LoadByEmail(command.DelegateTo)
        : _userStorage.Load(command.DelegateTo); 
        var isNotFriend = delegateTo ==
null || !_friendDataStore.IsFriend(command.DelegatedFromUserId, 
delegateTo.Id);
        if (isNotFriend)
        {
            item.RequestDelegationToInvited(delegatedBy, delegateTo !=
null ? delegateTo.Email : command.DelegateTo);
            MakeFriendsAndThenDelegate(command, delegateTo);
            return;
        } 
        item.RequestDelegationTo(delegatedBy, delegateTo);
    } 
    /// 
<summary>
    /// 
Hmm. No relationship between the users. Start by a friendship request.
    ///
</summary>
    ///
<param name="command"></param>
    ///
<param name="delegateTo"></param>
    private
void 
MakeFriendsAndThenDelegate(RequestTaskDelegation command, IUserLink delegateTo)
    {
        // Not a user yet, hence 
we need to connect using an ID,
        
// email can't be used since the user may loging with another 
one.
        if (delegateTo 
== null)
        { 
            var inviter = _userStorage.Load(command.DelegatedFromUserId); 
            var invited = _userStorage.GetInvitedByEmail(command.DelegateTo);
            if (invited ==
null)
            {
                invited = new 
InvitedUser(command.DelegateTo, inviter);
                _userStorage.Save(invited);
            } 
            var pendingDelegation =
new PendingDelegation
            {
                ActivationKey = invited.ActivationKey,
                FromUserId = command.DelegatedFromUserId,
                TaskId = command.TaskId
            };
            _todoItemStorage.StorePending(pendingDelegation); 
        }
        else
        {
            _todoItemStorage.StorePending(new 
PendingDelegation
            {
                DelegatedToUserId = delegateTo.Id,
                FromUserId = command.DelegatedFromUserId,
                TaskId = command.TaskId
            });
        } 
        var inviteCmd = 
new MakeFriend(command.DelegatedFromUserId, command.DelegateTo);
        _commandDispatcher.Dispatch(inviteCmd);
    } 
    /// 
<summary>
    /// 
Accepted our invitation, now let's make that delegation request for real.
    ///
</summary>
    ///
<param name="e">The 
event</param>
    public
void Handle(InvitationAccepted e)
    {
        // need to convert to 
using user id
        var 
delegations = _todoItemStorage.GetPendingByAcceptanceKey(e.ActivationKey);
        foreach (var 
delegation in delegations)
        {
            var newDelegation =
new PendingDelegation
            {
                DelegatedToUserId = e.InvitedUserId,
                FromUserId = e.InvitedByUserId,
                TaskId = delegation.TaskId
            };
            _todoItemStorage.StorePending(newDelegation);
        }
    } 
    /// 
<summary>
    /// 
Friendship requested, now we can request delegation
    ///
</summary>
    ///
<param name="e">The 
event</param>
    public
void Handle(FriendRequestAccepted e)
    {
        var delegations = _todoItemStorage.GetPendingByUserId(e.AcceptedBy);
        foreach (var 
delegation in delegations)
        {
            var item = _todoItemStorage.Load(delegation.TaskId);
            var to = _userStorage.Load(delegation.DelegatedToUserId);
            var from = _userStorage.Load(delegation.FromUserId);
            item.RequestDelegationTo(from, to);
            _todoItemStorage.Delete(delegation);
        }
    } 
    /// 
<summary>
    /// 
Need to remove a pending request.
    ///
</summary>
    ///
<param name="e">The 
event</param>
    public
void Handle(FriendRequestRejected e)
    {
        var delegations = _todoItemStorage.GetPendingByUserId(e.RejectedBy);
        foreach (var 
delegation in delegations)
        {
            _todoItemStorage.Delete(delegation);
            var item = _todoItemStorage.Load(delegation.TaskId);
            var user = _userStorage.Load(e.RejectedBy);
            item.RejectDelegation(user, e.Reason);
        }
    }
}
Summary
This article was created by Jonas Gauffin. Expect more articles in the future on 
the same subject.