Commands and Events

Messaging can help us to achieve loose coupling between components by introducing asynchronous fire and forget communication, this also help us maintain the autonomy of our component and preserve logical “Service” boundaries.

In general by using explicit naming, it should be clear what it is you expect the message handler to do. Combined with the “Single Responsibility Principle” (SRP) we can achieve better decomposition of our systems. For example, “UpdateUser” says very little about what this method is actually doing, while “UpdateUserPhoneNumber” or “ChangeUserPassword” is more like it :-).

It also means we are starting to slice and dice our entity to smaller units/properties that do only one thing, they change the state of the fields that reflect the unit of work’s effect of the state change (my mobile phone number has been created). Using the Command/Event semantics clarifies what is the intent and logical boundary of a message.

Commands: - Internal communication between components inside the boundary of a logical “Service” is done using commands. - Commands (as the name implies) can command another component within the boundary of the logical “Service”. - They change the state of the processing component. - They contain the data and context that the component (handler) needs in order to execute its task. - Commands are “Sent” (using bus.Send() using NServiceBus) to exactly one component (handler) (one to one communication).

Events: - Events are used for cross logical “Service” communications. - They notify of things that happened in the past. - They are light and contain only reference data like Ids and a small amount of context data. - Events are published (bus.Publish() using NServiceBus) - There is only one logical publisher and one or more subscribers. - Events can also be used inside a logical “Service” between internal loosely coupled components. To summaries: Use Commands with data inside you logical “Service” boundary to change state. Use Events with reference data for cross logical “Service” communications. Follow the Single Responsibility Principle, it will help reduce the size of your units of work. Reducing coupling is our objective.