Frage

Rebus has flexible system that allows me to specify different endpoints for different message types, either in web.config or by implementing a custom IDetermineMessageOwnership.

As far as I can tell, message ownership is represented simply by a string. Using the MSMQ transport, this string points to a queue to which the message is delivered. With RabbitMQ, the string is used as a topic for the message, which is then delivered to a generic exchange named "Rebus". Rebus is a nice fellow, so he also sets up a queue in the RabbitMQ server, using the same name, and makes a binding from topic to queue within the Rebus exchange.

My question is this: Is it possible to have Rebus not create queues and bindings, but still deliver the messages to an exchange with a relevant topic set for each message?

Declaring the queues and bindings manually will allow me to set up an awesome topic exchange, using bindings with wildcards and what not. Here is a nice illustration of a topic exchange with funky bindings, just to make my question look more sleek and sexy:

Illustration of topic exchange in RabbitMQ

War es hilfreich?

Lösung

Sounds to me like you want to do something like this:

Configure.With(yourFavoriteContainer)
         .Transport(t => t.UseRabbitMq(...)
                          .ManageSubscriptions()) //< BAM!!1
         .(...)

which lets Rebus take advantage of the fact that Rebus' RabbitMqMessageQueue implements IMulticastTransport, which in turn turns handling of all things multicast over to Rabbit.

It's just important that all of your Rabbit-enabled Rebus endpoints agree on letting Rabbit ManageSubscriptions - otherwise, weird stuff might happen ;)

It means that

  • when you bus.Subscribe<SomeEvent>, you bind a topic with the type name to the subscriber's input queue - e.g. "SomeEvent.SomeNamespace" -> myInputQueue
  • publishers publish events on a topic that is the type name - e.g. "SomeEvent.SomeNamespace"
  • message ownership is disregarded when subscribing
  • Rabbit will do the heavy lifting when doing multicast (which is what Rabbit users are mostly doing)

If you require even more flexibility, you can even take responsibility of deciding the topic to publish to for each .NET type, like so:

Configure.With(yourFavoriteContainer)
         .Transport(t => t.UseRabbitMq(...)
                          .ManageSubscriptions()
                          .AddEventNameResolver(type => DecideTopic(type))
         .(...)

You can add multiple event name resolvers if you want - they will be run in sequence until one of them returns something that is not null.

Does it make sense?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top