Getting on the IBus

0
75
9 min read

(For more resources related to this topic, see here.)

Why NServiceBus?

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 describe 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 if their order went through or not, and they’re not willing to retry for fear of being double charged, 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 designed it to be multithreaded (which was no small feat!) but we already maxed out the original server it was running on, and at the rate we’re adding clients it’s only a matter of time until we max out this 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 is integrating 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 emails is sent over and over until the failure no longer occurs.
  • I have a long-running process that gets kicked 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 spins forever.
  • We added latitude and longitude to our customer database, but now it is a nightmare to try to keep that information up-to-date. When a customer’s address changes, there is nothing to make sure the location information is also recalculated. There are dozens of procedures that update the customer address, and not all of them are under our department’s control.

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 so that you do not encounter deadlocks. It will ensure that valuable customer order data is not lost in the deep dark depths of a multi-megabyte log file.

By the end of the book, you’ll be able to build systems that can easily scale out, as well as up. You’ll 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 infrastructure and carefully applying the principles of service-oriented architecture, but that would be really time consuming. NServiceBus is the easiest 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.

Getting the code

We will be covering a lot of information very quickly in this article, so if you see something that doesn’t immediately make sense, don’t panic! Once we have the basic example in place, we will loop back and explain some of the finer points more completely.

There are two main ways to get the NServiceBus code integrated with your project, by downloading the Windows Installer package, and via NuGet. I recommend you use Windows Installer the first time to ensure that your machine is set up properly to run NServiceBus, and then use NuGet to actually include the assemblies in your project.

Windows Installer automates quite a bit of setup for you, all of which can be controlled through the advanced installation options:

  • NServiceBus binaries, tools, and sample code are installed.
  • The NServiceBus Management Service is installed to enable integration with ServiceInsight. .
  • Microsoft Message Queueing ( MSMQ ) is installed on your system if it isn’t already. MSMQ provides the durable, transactional messaging that is at the core of NServiceBus.
  • The Distributed Transaction Coordinator ( DTC ) is configured on your system. This will allow you to receive MSMQ messages and coordinate data access within a transactional context.
  • RavenDB is installed, which provides the default persistence mechanism for NServiceBus subscriptions, timeouts, and saga data.
  • NServiceBus performance counters are added to help you monitor NServiceBus performance.

Download the installer from http://particular.net/downloads and install it on your machine. After the install is complete, everything will be accessible from your Start Menu. Navigate to All Programs | Particular Software | NServiceBus as shown in the following screenshot:

The install package includes several samples that cover all the basics as well as several advanced features. The Video Store sample is a good starting point. Multiple versions of it are available for different message transports that are supported by NServiceBus. If you don’t know which one to use, take a look at VideoStore.Msmq.

I encourage you to work through all of the samples, but for now we are going to roll our own solution by pulling in the NServiceBus NuGet packages.

NServiceBus NuGet packages

Once your computer has been prepared for the first time, the most direct way to include NServiceBus within an application is to use the NuGet packages.

There are four core NServiceBus NuGet packages:

  • NServiceBus.Interfaces: This package contains only interfaces and abstractions, but not actual code or logic. This is the package that we will use for message assemblies.
  • 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 for unit testing NServiceBus endpoints and sagas.

The NuGet packages will also attempt to verify that your system is properly prepared through PowerShell cmdlets that ship as part of the package. However, if you are not running Visual Studio as an Administrator, this can be problematic as the tasks they perform sometimes require elevated privileges. For this reason it’s best to run Windows Installer before getting started.

Creating a message assembly

The first step to 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.

For this example, let’s pretend we’re creating a website like many on the Internet, where users can join and become a member. We will construct our project so that the user is created in a backend service and not in the main code of the website.

Follow these steps to create your solution:

  1. In Visual Studio, create a new class library project. Name the project UserService.Messages and the solution simply Example. This first project will be your messages assembly.
  2. Delete the Class1.cs file that came with the class project.
  3. From the NuGet Package Manager Console, run this command to install the NServiceBus.Interfaces package, which will add the reference to NServiceBus.dll.

    PM> Install-Package NServiceBus.Interfaces –ProjectName UserService.Messages

  4. Add a new folder to the project called Commands.
  5. Add a new class to the Commands folder called CreateNewUserCmd.cs.
  6. Add using NServiceBus; to the using block of the class file. It is very helpful to do this first so that you can see all of the options available with IntelliSense.
  7. Mark the class as public and implement ICommand. This is a marker interface so there is nothing you need to implement.
  8. Add the public properties for EmailAddress and Name.

When you’re done, your class should look like this:

using System; using System.Collections.Generic; using System.Linq; using System.Text; 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 will form the communication contract between the message sender and receiver. Unfortunately, we don’t have enough to run yet, so let’s keep moving.

Creating a service endpoint

Now we’re going to create a service endpoint that will handle our command message.

  1. Add a new class library project to your solution. Name the project UserService.
  2. Delete the Class1.cs file that came with the class project.
  3. From the NuGet Package Manager Console window, run this command to install the NServiceBus.Host package:

    PM> Install-Package NServiceBus.Host –ProjectName UserService

  4. 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, NServiceBus.Core.dll, and NServiceBus.dll
    • An App.config file
    • A class named EndpointConfig.cs
  5. In the service project, add a reference to the UserService.Messages project you created before.
  6. Right-click on the project file and click on Properties , then in the property pages, navigate to the Debug tab and enter NServiceBus.Lite under Command line arguments . This tells NServiceBus not to run the service in production mode while we’re just testing. This may seem obvious, but this is part of the NServiceBus promise to be safe by default, meaning you won’t be able to mess up when you go to install your service in production.

LEAVE A REPLY

Please enter your comment!
Please enter your name here