Book Image

Learning NServiceBus - Second Edition

By : David Boike
Book Image

Learning NServiceBus - Second Edition

By: David Boike

Overview of this book

Table of Contents (18 chapters)
Learning NServiceBus Second Edition
Credits
Foreword
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Sending a message from an MVC application


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.

Creating the MVC website

Let's follow these directions to get the MVC website set up. We will be using ASP.NET MVC 5 in Visual Studio 2013:

  1. 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.

  2. On the New ASP.NET Project dialog, select the Empty template and check the box to add folders and core references for MVC.

  3. From the NuGet Package Manager Console, run this command to install the NServiceBus package:

    PM> Install-Package NServiceBus –ProjectName ExampleWeb
    
  4. 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.

Note

NServiceBus also includes PowerShell cmdlets that make it a lot easier to add these configuration blocks. You can generate these sections of configuration using the Add-NServiceBusMessageForwardingInCaseOfFaultConfig cmdlet and the Add-NServiceBusUnicastBusConfig cmdlet.