Skip to content
mookid8000 edited this page Dec 28, 2012 · 19 revisions

"Routing", eh? Routing with the NServiceBus/MassTransit/Rhino ESB/Rebus class of service bus implementations is pretty simple: Either you do it manually, e.g. like so

advancedBus.Routing.Send("some.destination.queue.name", someMessage);

and

advancedBus.Routing.Subscribe<TSomeEvent>("some.destination.queue.name");

which is NOT the preferred way of routing things. This is mainly due to two facts:

  1. Hardcoding message destinations makes your system unflexible.
  2. Your application should not care about these things anyway - routing should be implemented by the bus.

How do you use the bus to route things?

Simple: Just use the overloads on IBus that don't take a destination endpoint as a parameter, e.g. like so:

bus.Send(someMessage);

and

bus.Subscribe<TSomeEvent>();

So how does the bus route things?

Rebus relies on the very simple [[IDetermineDestination]] interface in order to route messages - the interface provides a simple mapping from a message type to an endpoint name.

Rebus will look up a destination using this mechanism when you bus.Send messages, and when you bus.Subscribe to messages.

A word about publishing messages

Don't confuse this kind of routing with publishing - when you bus.Publish, the message will be sent to whoever has subscribed, provided that your configured subscription storage (the implementation of IStoreSubscriptions that you're using) has persisted the subscriptions as it should.

A word about replying to messages

Another thing is when you reply to a message, i.e. inside a message handler you bus.Reply - in this case, the reply will be sent to the return address as specified inside the message you're currently handling.

The duality

When you think of it, the messaging patterns Request/Reply and Publish/Subscribe are actually very much alike - only, it should have been called Subscribe/Publish, because that's the order of the sequence.

You can read and ponder some more here and here.

Configuring it

Rebus comes with two flavors of routing configuration, and they're very much alike. They both consist of mapping either a complete assembly of messages (what you'll most likely want to use) to an endpoint, or a single message type to an endpoint.

Doing it, Rebus style

First, you should configure Rebus to look up endpoint mappings in app.config/web.config:

Configure.With(...)
    .DetermineDestination(d => d.FromRebusConfigurationSection())
    //etc

Rebus style endpoint mappings should be included in the <rebus> configuration element in your app.config/web.config:

<configSections>
    <section name="rebus" type="Rebus.Configuration.RebusConfigurationSection, Rebus" />
</configSections>

will be in the top, and

<rebus inputQueue="my-service.input" errorQueue="my-service.error" workers="5">
    <endpoints>
        <add messages="MyApp.MyMessages.AnotherMessageType, Rebus.Tests" endpoint="another_message_endpoint"/>
        <add messages="MyApp.MyMessages" endpoint="some_message_endpoint"/>
    </endpoints>
</rebus>

further down. In this case, we have mapped AnotherMessageType to another_message_endpoint, whereas the rest of the entire MyApp.MyMessages assembly is mapped to some_message_endpoint.

Doing it, NServiceBus style

If you want to try out Rebus in a project where you've been using NServiceBus, you can configure Rebus to use your existing NServiceBus endpoint mappings - just do it like this:

Configure.With(...)
    .DetermineDestination(d => d.FromNServiceBusConfiguration())
    //etc

and leave the NServiceBus XML in place. If you want to lose the NServiceBus.Core assembly reference, you can change the NServiceBus configuration section (NServiceBus.Config.UnicastBusConfig, NServiceBus.Core) into a simple System.Configuration.NameValueSectionHandler.

Clone this wiki locally