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:
- Create a new project of type “Class Library”
- Make the project reference NServiceBus.DLL (“Get it now”)
- Create a class for each message, “tagging” each message class with the
IMessageinterface – see example below
public class CreateNewUserRequest : IMessage { public string Username { get; set; } }
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:
- Create a new project of type “Class Library”
- Make the project reference all the DLLs AND NServiceBus.Host.exe from the ZIP file
- Make the project reference the message DLL from above
- Make a class implement
IConfigureThisEndpoint– see example below - Make the endpoint configuration class implement either
AsA_Client,AsA_Server, orAsA_Publisher
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server { }
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 IMessageHandler<TMessage>. This requires you to implement one function, Handle. See example below:
public class HandleCreateNewUserRequest : IMessageHandler<CreateNewUserRequest> { public void Handle(CreateNewUserRequest message) { // ..... do stuff } }
But how does the service get access to the bus?
NServiceBus defaults to using Spring 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:
public class HandleCreateNewUserRequest : IMessageHandler<CreateNewUserRequest> { public IBus Bus { get; set; } public void Handle(CreateNewUserRequest message) { Bus.Send(new DoSomethingSomewhere()); } }
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:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" /> <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" /> </configSections> <MsmqTransportConfig InputQueue="client" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" /> <UnicastBusConfig> <MessageEndpointMappings> <add Messages="Messages" Endpoint="server" /> </MessageEndpointMappings> </UnicastBusConfig> </configuration>
In this XML file, I am configuring the following things:
- The
MsmqTransportConfigsection tells the generic host that this service can be reached atclient, which is just the name of a private message queue, which the framework will automatically create for us - The
UnicastBusConfig/MessageEndpointMappingssection tells the framework that all message types from the assemblyMessagesshould be sent to the message queueserver
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.
One Response to “NServiceBus for dummies who want to be smarties 1”
Sorry, the comment form is closed at this time.
[...] This post was mentioned on Twitter by UdiDahan and Andreas Öhlund, Mark Harris. Mark Harris said: RT @UdiDahan: Nice NServiceBus series of blog posts from @mookid8000 – http://bit.ly/2Epqs6 & http://bit.ly/3GH89S [...]