IRouter - rebus-org/Rebus GitHub Wiki
In several situations, Rebus will need to be able to determine who owns a particular message type - this is where the IRouter
comes in.
Why is this relevant? It's relevant in two scenarios: Whenever you want to send a message and whenever you want to subscribe to messages, and in both cases you have decided that you want to rely on the bus routing your messages.
Note that this need can disappear for publish/subscribe if the transport natively supports topic-based publish subscribe, or if Rebus is configured with a centralized subscription storage. In these cases, bus.Subscribe
will translate into some kind of subscribe operation at the transport level, or into directly registering the subscriber in the subscription storage.
When you send a message with await bus.Send(message)
, it is assumed that the message is some kind of command or request, and that the bus should figure out who the proper recipient is.
In this case, IRouter
will be called with the message, asking it where to send that message. If Rebus is configured with the type-based router like this:
Configure.With(...)
.(...)
.Routing(r => {
r.TypeBased()
.Map<SomeMessage>("some-queue");
})
.Start();
then the router will simply use the message's type to look up a destination, where e.g. the message type SomeMessage
would yield the queue some-queue
given the configuration shown above.
When you subscribe to messages of a given type with await bus.Subscribe<TEvent>()
, it is assumed that TEvent
is the type of some kind of event message, and that the bus should figure out who the publisher of those types of events is.
In this case, IRouter
will be called with the TEvent
type, asking it where to send a subscription message for the specified type.
It's just a way of putting it that will be true in most scenarios: If you structure your projects like this:
- SomeService
- SomeService.Messages
i.e. for each logical service in your application you have a correponding assembly of commands, requests/replies, and events, then you could say that the service owns those messages, and the following endpoint mapping would be sufficient for 99% of the cases in all the dependent services:
Configure.With(...)
.Routing(r => r.TypeBased().MapAssemblyOf<SomeService.Messages.SomeMessage>("some-service.input"))
.(...)
IRouter
is only relevant when you want the bus to route your messages (which you should most of the time). You can, however, do a await bus.Advanced.Routing.Send(destination, msg)
/ await bus.Advanced.Routing.Subscribe<TEvent>(destination)
in order to bypass the destination lookup, and have your messages sent explicitly to the specified endpoint.