NServiceBus for dummies who want to be smarties 1

NServiceBus for dummies who want to be smarties 1… first post: on how to get started creating services with NServiceBus.

How to create messages

Creating messages with NServiceBus consists of performing the following steps:

  1. Create a new project of type “Class Library”
  2. Make the project reference NServiceBus.DLL (“Get it now”) from the binaries folder
  3. Create a class for each message, “tagging” each message class with the IMessage interface – see example below

Note that IMessage is just a marker interface, so it does not require you to implement anything.

How to create a service

Creating a service with NServiceBus consists of performing the following steps:

  1. Create a new project of type “Class Library”
  2. Make the project reference NServiceBus.dll, NServiceBus.Core.dll, log4net.dll, and NServiceBus.Host.exe
  3. Make the project reference the message DLL from above
  4. Make a class implement IConfigureThisEndpoint – see example below
  5. Make the endpoint configuration class implement either AsA_Client, AsA_Server, or AsA_Publisher

How to run that service

Make each service project run the referenced NServiceBus.Host.exe inside its bin\Debug directory – e.g. CustomerService should, as its debug action, run the external program SolutionDir\CustomerService\bin\Debug\NServiceBus.Host.exe.

NServiceBus.Host.exe, referred to as “the generic host”, is actually a Windows service, that uses reflection to pick up all the assemblies that surround it, and use them to build a service.

This is why you need to implement IConfigureThisEndpoint – it’s a marker interface that tells the generic host to look for configuration in that class.

A nifty thing to do at this point, is to set your solution to debug multiple projects when you press F5 – do this by right clicking on the top node in solution explorer, select “Set startup projects…”, and make all your service projects start up when debugging.

How to do stuff in a service

Make a class in a service that implements IHandleMessages<TMessage>. This requires you to implement one function, Handle. See example below:

But how does the service get access to the bus?

NServiceBus defaults to using Spring.NET for DI, so dependencies are automagically resolved – which also includes the bus! Which in turn means that the following code snippet can send messages by using the bus:

Ok, but where does the message go?

Well, that depends – for this stuff to run, we need to do a tad more configuration by supplying each service with an app.config. E.g. like so:

In this XML file, I am configuring the following things:

  • The MsmqTransportConfig section tells the generic host that this service can be reached at client, which is just the name of a private message queue, which the framework will automatically create for us
  • The UnicastBusConfig/MessageEndpointMappings section tells the framework that the message types from the assembly Messages are owned by the service behind the server endpoint

Why do I say that the messages “are owned by the service behind the server endpoint”? Why not just say that the message endpoint mappings configure the destination? Consider this table:

Operation Who performs the operation Who has IHandleMessages<TMessage>
bus.Send client server
bus.Publish server client

As you can see, there’s more to the endpoint mappings than just specifying the message destination – a more careful and precise description is that the endpoint mappings specify who owns the messages.

Please pay some respect and awe to the MaxRetries, ErrorQueue, and NumberOfWorkerThreads attributes – how cool is that?! It means that all exceptions that may happen inside your message handlers should not be handled by you, just let them bubble up to the framework and let it retry delivery up to 5 times until successful, or else the message will go to the error queue. That totally rids you of handling those pesky exceptions coming from your database transaction (hopefully rarely, or else your database is a bottleneck) being selected as the deadlock victim, temporarily unavailable external services unable to communicate, etc. Handling those things is truly the job of a framework.

Conclusion

That concludes today’s “NServiceBus for dummies who want to be smarties”. This was how to go about creating a simple service which is capable of receiving a message, and in the message handler it can send a message.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.