Before diving in, we should take a moment to consider why NServiceBus might be a tool worth adding to your repertoire. If you're eager to get started, feel free to skip this section and come back later.
So what is NServiceBus? It's a powerful, extensible framework that will help you to leverage the principles of Service-oriented architecture (SOA) to create distributed systems that are more reliable, more extensible, more scalable, and easier to update.
That's all well and good, but if you're just picking up this book for the first time, why should you care? What problems does it solve? How will it make your life better?
Ask yourself whether any of the following situations describes you:
My code updates values in several tables in a transaction, which acquires locks on those tables, so it frequently runs into deadlocks under load. I've optimized all the queries that I can. The transaction keeps the database consistent but the user gets an ugly exception and has to retry what they were doing, which doesn't make them very happy.
Our order processing system sometimes fails on the third of three database calls. The transaction rolls back and we log the error, but we're losing money because the end user doesn't know whether their order went through or not, and they're not willing to retry for fear of being charged twice, so we're losing business to our competitor.
We built a system to process images for our clients. It worked fine for a while, but now we've become a victim of our own success. We made it multithreaded, which was a challenge. Then we had to replace the server it was running on because it maxed out. We're adding more clients and it's only a matter of time until we max out the new one too! We need to scale it out to run on multiple servers but have no idea how to do it.
We have a solution that integrates with a third-party web service, but when we call the web service, we also need to update data in a local database. Sometimes, the web service times out, so our database transaction rolls back, but sometimes, the web service call does actually complete at the remote end, so now our local data and our third-party provider's data are out of sync.
We're sending emails as part of a complex business process. It is designed to be retried in the event of a failure, but now customers are complaining that they're receiving duplicate emails, sometimes dozens of them. A failure occurs after the email is sent, the process is retried, and the email is sent over and over until the failure no longer occurs.
I have a long-running process that kicks off from a web application. The website sits on an interstitial page while the backend process runs, similar to what you would see on a travel site when you search for plane tickets. This process is difficult to set up and fairly brittle. Sometimes, the backend process fails to start and the web page just keeps loading forever.
We have a batch job that runs every night during off hours, but it's taking so long to run that it's intruding on regular business hours. Plus waiting for the batch job is a headache. It needs to be more real-time.
We don't want to keep investing in on-premises infrastructure to deal with potential spikes in traffic. We need to figure out how to transition some of our business processes to run in the cloud.
If any of these situations has you nodding your head in agreement, I invite you to read on.
NServiceBus will help you to make multiple transactional updates utilizing the principle of eventual consistency to reduce database locking and blocking and make deadlocks easy to deal with in a reliable way. It will ensure that valuable customer order data is not lost in the deep dark depths of a multi-megabyte logfile.
By the end of the book, you'll be able to build systems that can easily scale out as well as up. You'll also be able to reliably perform non-transactional tasks such as calling web services and sending emails. You will be able to easily start up long-running processes in an application server layer, leaving your web application free to process incoming requests and you'll be able to unravel your spaghetti codebases into a logical system of commands, events, and handlers that will enable you to more easily add new features and version the existing ones.
You could try to do this all on your own by rolling your own messaging, but that would be really dangerous and wasteful. It is a far better strategy to take advantage of all of the industry-leading expertise that has been applied in NServiceBus in the last several years, and concentrate on what your business does best. NServiceBus is the easiest and most capable solution to solve the aforementioned problems without having to expend too much effort to get it right, allowing you to put your focus on your business concerns, where it belongs.
So if you're ready, let's get started creating an NServiceBus solution.
We will be covering a lot of information very quickly in this chapter, so if you see something that doesn't immediately make sense, don't panic! Once we have the basic example in place, we will look back and explain some of the finer points in more detail.
To get the actual NServiceBus binaries, we will use NuGet exclusively, but before we get started on our first project, we should download and run the installer for the entire Particular Service Platform, which will ensure that your machine is set up properly to run NServiceBus solutions. Additionally, the platform installer will install several other helpful applications that will assist in your NServiceBus development, which we will cover in more detail in Chapter 8, The Service Platform.
Download the installer from http://particular.net/downloads and run it on your machine. The following screenshot depicts the applications installed by the platform installer:

You should select all the options that are available to you. There are two options for ServiceMatrix because of differences in how Visual Studio handles add-ins between Visual Studio 2012 and 2013, so you can install whichever matches the version of Visual Studio you use.
In addition to the Service Platform apps, the installer does several things to get your system ready to go:
Microsoft Message Queueing (MSMQ): This is installed on your system if it isn't already. MSMQ is the default message transport that provides the durable, transactional messaging that is at the core of NServiceBus (this is only one messaging transport supported by NServiceBus. We will learn about others in Chapter 4, Hosting).
Distributed Transaction Coordinator (DTC): This is configured on your system. It will coordinate transactional data access between resources (such as MSMQ) that support it in order to guarantee that messages are processed once and only once.
NServiceBus performance counters: These are added to help you monitor NServiceBus' performance.
Now that our system is ready to go, we can get started building our first solution by pulling in the NServiceBus NuGet packages.
Once your computer has been prepared for the first time, you have to include NServiceBus within an application using the NuGet packages.
There are three core NServiceBus NuGet packages:
NServiceBus
: This package contains the core assembly with most of the code that drives NServiceBus, except for the hosting capability. This is the package we will reference when we host NServiceBus within our own process, such as in a web application.NServiceBus.Host
: This package contains the service host executable. With the host, we can run an NServiceBus service endpoint from the command line during development, and then install it as a Windows service for production use.NServiceBus.Testing
: This package contains a framework used to unit-test NServiceBus endpoints and sagas. We will cover this in more detail in Chapter 6, Sagas.
If you try installing the NuGet packages first, they will attempt to detect this and direct you to download the entire Particular Service Platform from the website. Without running the installer, it's difficult to verify that everything on your machine is properly prepared, so it's best to download and run the installer before getting started.
Note
In previous versions, there was also a package called NServiceBus.Interfaces
. It has now been deprecated. Most users should be using unobtrusive mode conventions, which we will cover in depth in Chapter 5, Advanced Messaging. For simple exercises, wherever NServiceBus.Interfaces
is used, it should be replaced by the core NServiceBus
package.
For this example, let's pretend we're creating a simple website that users can join and become a member of. We will construct our project so that the user is created in a backend service and not in the main code of the website.
The following diagram depicts our goal. We will have an ASP.NET MVC web application that will send a command from the HomeController
process, and then the command will be handled by another process called UserService
.

The first step while creating an NServiceBus system is to create a messages assembly. Messages in NServiceBus are simply plain old C# classes. Like the WSDL document of a web service, your message classes form a contract by which services communicate with each other.
Follow these steps to create your solution:
In Visual Studio, create a new project by creating a new class library. Name the project
UserService.Messages
and the solution, simplyExample
. This first project will be your messages assembly.Delete the
Class1.cs
file that came with the class project.From the NuGet Package Manager Console, run this command to install the
NServiceBus
package, which will add the reference toNServiceBus.Core.dll
:PM> Install-Package NServiceBus –ProjectName UserService.Messages
Add a new folder to the project called
Commands
.Add a new class file called
CreateNewUserCmd.cs
to theCommands
folder.Add
using NServiceBus;
to theusing
block of the class file. It is very helpful to do this first so that you can see all the options available with IntelliSense.Mark the class as
public
and implementICommand
. This is a marker interface, so there is nothing you need to implement.Add the
public
properties forEmailAddress
andName
.
When you're done, your class should look like this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NServiceBus; namespace UserService.Messages.Commands { public class CreateNewUserCmd : ICommand { public string EmailAddress { get; set; } public string Name { get; set; } } }
Congratulations! You've created a message. This new message will form the communication contract between the message sender and receiver. This is just a message; now you need to create a service that can receive and process it.
Now we're going to create a service endpoint—a process that will host code to handle our command message:
Add a new class library project to your solution. Name the project
UserService
.Delete the
Class1.cs
file that came with the class project.From the NuGet Package Manager Console window, run this command to install the
NServiceBus.Host
package:PM> Install-Package NServiceBus.Host –ProjectName UserService
Take a look at what the host package has added to your class library. Don't worry; we'll cover this in more detail later:
References to
NServiceBus.Host.exe
andNServiceBus.Core.dll
An
App.config
fileA class named
EndpointConfig.cs
Project debug settings to execute
NServiceBus.Host.exe
when we debug
In the service project, add a reference to the UserService.Messages project you created before.
In the
EndpointConfig.cs
class that was generated, replace the textPLEASE_SELECT_ONE
withInMemoryPersistence
. You may need to add ausing NServiceBus.Persistence;
declaration to the file if you don't have a tool such as ReSharper to do it for you.
Now that we have a service endpoint to host our code, we will create a message handler within the endpoint that will process our message when it arrives:
Add a new class called
UserCreator.cs
to the service.Add three namespaces to the
using
block of the class file:using NServiceBus; using NServiceBus.Logging; using UserService.Messages.Commands;
Mark the class as
public
.Implement
IHandleMessages<CreateNewUserCmd>
.Implement the interface using Visual Studio's tools. This will generate a
Handle(CreateNewUserCmd message)
stub method.
Normally, we would want to create the user here with calls to a database. In order to keep the examples straightforward, we will skip the details of database access and just demonstrate what will happen by logging a message.
With NServiceBus, you can use any logging framework you like without being dependent upon that framework. NServiceBus internally includes a logging system that logs to both console and file, with an API that looks very much like log4net (previous versions of NServiceBus actually used the log4net framework directly). In Chapter 7, Advanced Configuration, you will learn how to easily swap these out for the real log4net
framework, NLog
framework, or implement an adapter for any logger we like. For now, we are more than content with the built-in logging implementation via the NServiceBus.Logging
namespace.
Now lets finish our fake implementation for the handler:
Above the
Handle
method, add an instance of a logger:private static readonly ILog log = LogManager.GetLogger(typeof(UserCreator));
To handle the command, remove
NotImplementedException
and replace it with the following statement:log.InfoFormat("Creating user '{0}' with email '{1}'",message.Name,message.EmailAddress);
When you're done, your class should look like this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UserService.Messages.Commands; using NServiceBus; namespace UserService { public class UserCreator : IHandleMessages<CreateNewUserCmd> { private static readonly ILog log = LogManager.GetLogger(typeof(UserCreator)); public void Handle(CreateNewUserCmd message) { log.InfoFormat("Creating user '{0}' with email '{1}'", message.Name, message.EmailAddress); } } }
Now we have a command message and a service endpoint to handle it. Its okay if you don't understand quite how all of this connects yet. Next, we need to create a way to send the command.
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
An ASP.NET MVC web application will be the user interface for our system. It will be sending a command to create a new user to the service layer, which will be in charge of processing it. Normally this would be from a user registration form, but in order to keep the example to the point, we'll take a shortcut and enter the information in the form of query string parameters, and return data as JSON.
Note
Because we will be viewing JSON data directly within a browser, it would be a good idea to ensure that your browser supports displaying JSON directly instead of downloading it.
Firefox and Chrome natively display JSON data as plain text, which is readable but not very useful. Both browsers have an extension available, called JSONView (although they are unrelated), which allows you to view the data in a more readable, indented format. Either of these options will work fine, so you can use whichever browser you prefer.
Beware that Internet Explorer will try to download JSON data to a file, which makes it cumbersome to view the output.
Let's follow these directions to get the MVC website set up. We will be using ASP.NET MVC 5 in Visual Studio 2013:
Add a new project to your solution. Select the ASP.NET Web Application template and name the project
ExampleWeb
. Select the Empty template and the Razor view engine.On the New ASP.NET Project dialog, select the Empty template and check the box to add folders and core references for MVC.
From the NuGet Package Manager Console, run this command to install the NServiceBus package:
PM> Install-Package NServiceBus –ProjectName ExampleWeb
Add a reference to the UserService.Messages project you created before.
Because the MVC project isn't fully controlled by NServiceBus, we have to write a bit of code to get it running.
To accomplish this, create a class file within the root of your MVC application and name it ServiceBus.cs
. Then, fill it with following code. For the moment, don't worry about what this code does:
using NServiceBus; namespace ExampleWeb { public static class ServiceBus { public static IBus Bus { get; private set; } private static readonly object padlock = new object(); public static void Init() { if (Bus != null) return; lock (padlock) { if (Bus != null) return; var cfg = new BusConfiguration(); cfg.UseTransport<MsmqTransport>(); cfg.UsePersistence<InMemoryPersistence>(); cfg.EndpointName("ExampleWeb"); cfg.PurgeOnStartup(true); cfg.EnableInstallers(); Bus = NServiceBus.Bus.Create(cfg).Start(); } } } }
That was certainly a mouthful! Don't worry about remembering this. The API makes it pretty easy to discover things you need to configure, through IntelliSense. You will learn more about this code in Chapter 4, Hosting, and I'll explain everything that's going on.
For now, it is sufficient to say that this is the code that initializes the service bus within our MVC application and provides access to a single static instance of the IBus
interface that we can use to access the service bus.
Tip
You may notice the locking pattern used in the previous code to ensure that the Bus instance is initialized only once. This is just one strategy. You could also, for example, utilize a Lazy<IBus>
instance to the same effect.
Now that we've established the ServiceBus
class, we need to call the Init()
method from our Global.asax.cs
file so that the Bus
property is initialized when the application starts up:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
ServiceBus.Init();
}
Now NServiceBus has been set up to run in the web application, so we can send our message. Create a HomeController
class and add these methods to it:
public ActionResult Index() { return Json(new { text = "Hello world." }); } public ActionResult CreateUser(string name, string email) { var cmd = new CreateNewUserCmd { Name = name, EmailAddress = email }; ServiceBus.Bus.Send(cmd); return Json(new { sent = cmd }); } protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior) { return base.Json(data, contentType, contentEncoding, JsonRequestBehavior.AllowGet); }
The first and last methods aren't very important. The first returns some static JSON for the /Home/Index
action because we aren't going to bother adding a view for it. The last one is for convenience, to make it easier to return JSON data as a result of an HTTP GET
request.
However, the highlighted method is important because this is where we create an instance of our command class and send it to the bus via the ServiceBus.Bus
static instance. Lastly, we return the command to the browser as JSON data so that we can see what we created.
The last step is to add some NServiceBus configuration to the MVC application's Web.config
file. We need to add two sections of configuration. We already saw MessageForwardingInCaseOfFaultConfig
in the app.config
file that NuGet added to the service project, so we can copy it from there. However, we need to add a new section called UnicastBusConfig
anyway, so the XML for both is included here for convenience:
<configuration> <configSections> <section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" /> <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" /> </configSections> <MessageForwardingInCaseOfFaultConfig ErrorQueue="error" /> <UnicastBusConfig> <MessageEndpointMappings> <add Messages="UserService.Messages" Endpoint="UserService" /> </MessageEndpointMappings> </UnicastBusConfig> <!-- Rest of Web.config --> </configuration>
The first highlighted line determines what happens to a message that fails. This will be covered in more depth in Chapter 3, Preparing for Failure. The second highlighted line determines routing for messages. This will be covered in more depth in the Publish/Subscribe section of Chapter 2, Messaging Patterns, but for now, it is sufficient to say that it means that all messages found in the UserService.Messages
assembly will be sent to the UserService
endpoint, which is our service project.
One thing that will be useful when developing NServiceBus solutions is being able to specify multiple startup projects for a solution:
In Solution Explorer, right-click on the solution file and click on Properties.
From the left side, navigate to Common Properties | Startup Project.
Select the Multiple startup projects radio button.
Set the Action for the service project and the MVC project to Start and order them such that the MVC project starts last.
Click on OK.
Now build the solution if you haven't already, and assuming there are no compilation errors, click on the Start Debugging button or press F5.
So what happens now? You get a result that looks like what is shown in the following screenshot:

When you run the solution, both the MVC website and a console window should appear as shown in the preceding screenshot. As we can see, the browser window isn't terribly exciting right now. It's just showing the JSON results of the /Home/Index
action. The console window is far more interesting.
If you remember, we never created a console application; our service endpoint was a class project. When we included the NServiceBus.Host
NuGet package, a reference to NServiceBus.Host.exe
was added to the class project (remember that a .NET executable is also an assembly and it can be referenced by another project) and the project was set to run that executable when you debug it.
NServiceBus uses different colors to log messages of different levels of severity. INFO messages are logged in white, and WARN messages are displayed in yellow. In addition, there can be DEBUG messages, also displayed in white, or ERROR and FATAL messages which are both logged in red. By default, the INFO log level is used for display, which filters out all the DEBUG messages here, and luckily we don't have any ERROR or FATAL messages.
The entire output is too much to show in a single screenshot. It's worth reading through, even though you may not understand everything that's going on quite yet. Here are some of the important points:
NServiceBus reports how many total message types it has found. In my example, two messages were found. Only one of them is ours; the other is an administrative message, which is used internally by NServiceBus. If it had said that no messages were found, that would have been distressing! We will revisit this message in Chapter 5, Advanced Messaging.
The License Manager checks for a valid license. You can get a free trial license that allows unrestricted non-production use for a limited time. After that, you need to purchase a commercial license, although Particular may be willing to extend your trial if your situation merits it. For all questions about licensing, go to http://particular.net/licensing. Every situation is different, so don't hesitate to contact Particular to find out which licensing structure will work best for you.
The status of many features is listed for debugging purposes.
NServiceBus checks for the existence of several queues and creates them if they do not exist. In fact, if we go to the Message Queuing Manager, we will see that the following private queues have now been created:
audit
error
exampleweb
exampleweb.retries
exampleweb.timeouts
exampleweb.timeoutdispatcher
userservice
userservice.retries
userservice.timeouts
userservice.timeoutsdispatcher
Note
If you installed the Service Platform, there could be queues for error.log
and several queues starting with particular.servicecontrol
as well. We'll discuss these in depth in Chapter 8, The Service Platform.
That's a lot of plumbing that NServiceBus takes care of for us! But this just gets the endpoint ready to go. We still need to send a message.
Visual Studio will likely give you a different port number for your MVC project than the number in the preceding example, so change the URL in your browser to the following, keeping the host and port the same. Feel free to use your own name and email address:
/Home/CreateUser?name=David&email=david@example.com
Look at what happens in your service window:
INFO UserService.UserCreator Creating user 'David' with email 'david@example.com'
This might seem simple, but consider what had to happen for us to see this message. First, in the MVC website, an instance of our message class was serialized to XML. Then that payload was added to an MSMQ message with enough metadata to describe where it came from and where it needs to go. The message was sent to an input queue for our background service, where it waited to be processed until the service was ready for it. The service pulled the message from the queue, deserialized the XML payload, and was able to determine a handler that could process the message. Finally, our message handler was invoked, which resulted in the message being output to the log.
This is a great start, but there is a great deal more to discover.
In this chapter, we created an MVC web application and an NServiceBus-hosted service endpoint. Through the web application, we sent a command to the service layer to create a user where we just logged the fact that the command was received, but in real life, we would likely perform database work to actually create the user. For our example, our service was running on the same computer, but our command can just as easily be sent to a different server, enabling us to offload work from our web server.
In the next chapter, we will take the code we developed in this chapter and extend it using Publish/Subscribe to enable decoupling services from each other. Then we will start to discover the true power that NServiceBus has to offer.