In the previous kata we sent a message from one application to another. This is a common pattern in messaging systems. In this kata we're going to look at a different pattern: publishing a message.
- Kata 1 - Sending a message
- Kata 2 - Publishing a message
- Kata 3 - Switching transports
- Kata 4 - Long running processes
- Kata 5 - Timeouts
- Kata 6 - When things go wrong
The Problem
It is great being able to send a message from one system to another - you can instruct a remote system to take some action which you don't know how to do. For instance sending an email. In a large system lots of processes will likely result in an email but if you can centralize the logic around how to send an email it makes it very easy to do things like change email providers as that functionality is isolated and independent.
If you looked at my solution for the first Kata then you might have notice that I named my message EatCake
this is named in the imperative form. This is a common pattern in messaging systems and is, I think, remarkably helpful to understand the command pattern. When you issue a command you know exactly who or what you're commanding and in the same way the command is sent to a known endpoint.
Sometimes, however, you don't have a particular target in mind and you just want to let other systems know that you have done something. In this case you can publish a message. Unlike a command you don't know who is going to act on it - it may be nobody or it may be multiple people. In a messaging system we call this an Event
.
Let's extend our cake eating example to imagine some consequences of what might happen if I happily reported that I had eaten cake: CakeEaten
. Finding out that the cake had been eaten the bakery might start baking more cake assuming that I'd want more (very likely). My gym might free up a treadmill knowing that my cake-induced guilt might drive me to run until I'd burned off the delicious butter-cream. It might also be of interest to my wife who can text me and see if I enjoyed the cake. I don't actually know who would be interested in the event so it is the responsibility of those who are interested to subscribe to the event.
The Kata
Using the solution to the first kata as a starting point extend the system to publish a CakeEaten
message. Subscribe to the message in the sender and write out a message to the console. Also create another new project similar to the others and have it subscribe to the message.
My Solution
- Create a new message in the messages assembly
1 | namespace messages; |
- Modify the Hander in the receiver to publish the new event. Notice that we have access to a
IMessageHandlerContext
which we can use to publish messages.
1 | using messages; |
- Modify the sender to subscribe to the event by adding a Handler to the project.
1 | using messages; |
- Optionally modify the sender to remain running so that it can receive the message. This is done by adding a
Console.ReadLine()
at the end of theMain
method.
1 | using NServiceBus; |
Pause here and ensure that when running the sender and receiver that you see both a message sent and published.
- Create a new project to act as a second subscriber or receiver
1 | dotnet new console -o anotherReceiver |
- Add a subscriber class to the project
1 | using messages; |
- Update the Program.cs to initiate NServiceBus
1 | using messages; |
Things to try now:
- Start the receiver and the another receiver then the sender - ensure you see messages flowing correctly
- Start services in different orders and see which messages might be lost
Sending and receiving messages and publishing messages should now be working great. But to get this example going we've made some simplifications which we'll have to address in the next kata.