It is very difficult to build a distributed software system correctly from scratch. You could read all 736 pages of the Enterprise Integration Patterns book (an excellent though very dry reference) and then spend months creating, testing, and documenting a communication framework so that different services can talk to each other. Or instead, you could use a framework that incorporates all those design patterns and guides you straight into the pit of success.
NServiceBus combines decades of distributed systems design experience and expertise and distills it into one easy-to-use framework. In this tutorial, you'll see how NServiceBus takes all the grunt work out of system design by handling all of the infrastructure complexity for you, taking system design best practices like reliability, failure recovery, and extensibility and baking them right into the software, guiding you toward the pit of success.
You'll also see how the additional tools in the Particular Service Platform make it easy to manage, monitor, and debug.
This tutorial skips over some concepts and implementation details in order to get up and running quickly. If you'd prefer to go more in-depth, check out our NServiceBus step-by-step tutorial. It will teach you the NServiceBus API and important concepts necessary to learn how to build successful message-based software systems.
The demo solution doesn't require any prerequisites — no message queue or database to install, just Visual Studio. To get started, download the solution, extract the archive, and then open the RetailDemo.sln file.
The solution contains five projects. The ClientUI, Sales, and Billing projects are endpoints that communicate with each other using NServiceBus messages. The ClientUI endpoint is implemented as a web application and is the entry point to our system. The Sales and Billing endpoints, implemented as console applications, contain business logic related to processing and fulfilling orders. Each endpoint references the Messages assembly, which contains the definitions of messages as simple class files. The Platform project will provide a demonstration of the Particular Service Platform, but initially, its code is commented out.
As shown in the diagram below, the ClientUI endpoint sends a PlaceOrder command to the Sales endpoint. As a result, the Sales endpoint will publish an OrderPlaced event using the publish/subscribe pattern, which will be received by the Billing endpoint.
The solution mimics a real-life retail system where the command to place an order is sent as a result of customer interaction, and the processing occurs in the background. Publishing an event allows us to further isolate the code to bill the credit card from the code to place the order, reducing coupling and making the system easier to maintain over the long term. Later in this tutorial, we'll see how to add a second subscriber to that event in a new Shipping endpoint which will begin the process of shipping the order.
The solution is configured to have multiple startup projects, so when we run the solution (Debug > Start Debugging or press F5) it should open three console applications, one for each messaging endpoint. One of these will open the web application in your browser. (The Particular Service Platform Launcher console app will also open but not do anything. Depending on your version of Visual Studio, it may persist or immediately close.)
Did all three windows appear?
- For Visual Studio Code users, ensure the Debug All launch configuration is selected from the dropdown list under the Run and Debug tab.
- In versions prior to Visual Studio 2019 16.1, there is a bug (Link 1, Link 2) that will sometimes prevent one or more projects from launching with an error message. If this is the case, stop debugging and try again. The problem usually happens only on the first attempt.
In the ClientUI web application, click the Place order button to place an order, and watch what happens in other windows.
It may happen too quickly to see, but the PlaceOrder command will be sent to the Sales endpoint. In the Sales endpoint window we see:
INFO Received PlaceOrder, OrderId = 9b16a5ce INFO Publishing OrderPlaced, OrderId = 9b16a5ce
As shown in the log, the Sales endpoint then publishes an OrderPlaced event, which will be received by the Billing endpoint. In the Billing endpoint window we see:
INFO Billing has received OrderPlaced, OrderId = 9b16a5ce
In the ClientUI web application, go back and send more messages, watching the messages flow between endpoints.
Now that the project is up and running, let's break it!