Convention over configuration in NServiceBus 3.0

One of the key goals for NServiceBus 3.0 is to remove much of the need for configuration and there by improve the out of the box experience. In order to achieve this we have introduced the concept of a EndpointName that will be used to control our naming conventions.

The endpoint name is the name of a individual endpoint and must be unique across your solution. The only exception to this rule is when you are scaling out using the master node concept where the same logical endpoint would reside on many physical servers, more on that in a upcoming post.

Conventions that use the endpoint name

The following conventions use the endpoint name to configure various parts of NServiceBus. Note that the {masternode} will be localhost if not specified.

  • Local address – The local address (input queue) of your endpoint will be the {endpointname}
  • Subscriptions – If you use the Msmq subscription storage the name of the queue used to store the subscribers will be {endpointname}.subscriptions
  • Raven database name – The database name when storing data related to the endpoint will be {endpointname}
  • Timeout manager address - The address of the timeout manager will be {endpointname}.timeouts@{masternode}
  • Gateway input address - The address where the gateway will pickup outgoing messages will be {endpointname}.Gateway@{masternode}
  • Gateway url - If you use the http/https channel the url that the gateway will listen to is defaulted to http(s)://localhost/{endpointname}
  • Distributor input queue – The input queue of the distributor will be {endpointname}@{masternode}
  • Distributor control queue - The control queue of the distributor will be {endpointname}.distributor.control@{masternode}
  • Distributor storage queue - The local storage queue of the distributor will be {endpointname}.distributor.storage

How to specify the endpoint name

There are multiple ways that you can define the endpoint name. Lets look at them one by one.

  • If not specified by the user the namespace of the class implementing IConfigureThisEndpoint will be used as the endpoint name when running the NServiceBus host. If your project is called MyServer and the config is in the root this will result in the endpoint name “MyServer”. This is the recommended way to name a endpoint.
  • If not specified by the user when custom hosting NServiceBus the namespace of the class calling NServiceBus.Configure.With() will be used. For websites this will likely be the namespace of your global.asax.cs
  • You can set the endpoint name using the [EndpointName] attribute on your endpoint configuration.
  • You can implement the INameThisEndpoint interface on your endpoint config
  • If you specify a explicit service name when installing the NServiceBus host this will be used as endpoint name: /serviceName:”"MyEndpoint”
  • You can specify a endpoint name when running the NServiceBus host: /endpointName:”"MyEndpoint”
As you can see there is lots of ways to do this. But if all the above is not enough you can define your own convention using:
Configure.DefineEndpointName(()=>{….})

Upgrading from NServiceBus 2.6

Users upgrading from 2.6 need to name their endpoint to the same name as their current input queue since there is no way to explicitly set the input queue in NServiceBus 3.0

In closing

Naming your endpoint will be a very important thing going forward and the framework will try to push you in that direction by not making it to easy for you to override. This will hope fully help us further improve our “convention over configuration” support make it even easier for you to build, deploy and run NServiceBus in the future.

This entry was posted in NServiceBus. Bookmark the permalink. Both comments and trackbacks are currently closed.
  • Erik Lindström

    What about the error queue. It is not created during startup now?
    Is that the ‘MessageForwardingInCaseOfFaultConfig’ that should be used?

    • Anonymous

      Yes that is correct

  • Pingback: Using RavenDB in NServiceBus – Connecting

  • http://twitter.com/tapmantwo Richard Tappenden

    How do you recommend managing the EndPoint names for Sagas? I see that you suggest the ‘IConfigureThisEndPoint’ convention as best practise, but according to other documents, it seems that because a Saga can handle multiple messages, you may want to deploy it with a different end point name per message? I’d be interested to know what your recommendations are here.

    • Anonymous

      You’re free to deploy sagas to any endpoint you like. But if you spread the same saga over more than one endpoint you need to configure the endpoints to share the same database using the connection string option of .RavenPersistence().

      Was that what you where asking for?

      • http://twitter.com/tapmantwo Richard Tappenden

         Not quite (sorry I don’t think I explained it too well).

        Essentially, we’re looking at creating best practises and references for using NServiceBus & NServiceBus sagas.  One of the best practises we’ve picked upon from the documentation (and agree with wholeheartedly) is that each message type should have it’s own queue, that there should only be one application that consumes the messages in that queue, and that said application only handles one message type.  This goes in line nicely with SRP etc.

        However, Sagas are an exception, in that they themselves may need to handle multiple message types.

        What we have found is that so far, our Saga effectively has one input queue, so that goes against our initial principle of one queue per message type. Having read the documentation on the website, it suggests that “As such, it is recommended to deploy the saga logic to each of the endpoints responsible for
        each message type”.

        This is where I’m getting a bit confused.  Does this mean host multiple versions of the same Saga, but with a different end point name (to correlate with each of the different messages it handles)? If so, how do we best manage that end point naming? If we stick with the default (i.e. using the IConfigureThisEndpoint convention), it will always have the same name.

        Does this explain the question a little bit further? I guess to summarise;
        1) Do we need to host sagas multiple times with different end point names, so that we can keep to the one queue per message type guidance?
        2) If so, how do we best control that end point name for each instance.  Can we do this through the configuration somehow? (In Azure, the ‘LocalAddress’ property of the UnicastBusConfig seems to be supported, but it fails outside of Azure).
        3) If not, is there a different way that we can get Saga’s to look at messages across different input queues.

        I hope this is clear – and really appreciate your input on this.

        • Steve Friend

           I’m really interested in this as well.  I posted to the yahoo user group about Local Address, but I haven’t heard anything back yet. 

          The reason I asked was for exactly this kind of thing though.  I’m trying to work through how you should deploy this kind of thing – the point Andreas makes about the .RavenPersistence() is really interesting.  It feels as though doing that would be going against the way NServiceBus wants you to work, but I’m struggling to see another option?

          • Anonymous

            LocalAddress is not used in 3.0 (think its only used for Azure). The only way to influence the input queue is to name the endpoint accordingly.

        • Anonymous

          Given that we can now scale out very easy using the MasterNode concept the guidance in 3.0 would be to keep sagas on the same endpoint. If you still want to split them you need to use a explicit connection string and point all the endpoints for a given saga to the same database.

          Does that make sense?

          • http://twitter.com/tapmantwo Richard Tappenden

             It does – but does this have an impact on how we structure? i.e. do the various different messages types a saga handles all go into the same queue?

  • Edward Adjei

    Can I host multiple endpoints in one process?