antonyvorontsov / RabbitMQ.Client.Core.DependencyInjection

.Net Core library-wrapper of RabbitMQ.Client for Dependency Injection.
MIT License
111 stars 36 forks source link

Wildcard Bindings are not supported #12

Closed vic10us closed 4 years ago

vic10us commented 4 years ago

When using exchange routing rules with topic exchanges it is possible to bind a queue to an exchange with a wildcard routing key example:

Exchange: Bob.The.Builder Queue: Yes.We.Can Routing Key Binding: Can.We.Build.#

Produced message Exchange: Bob.The.Builder Routing Key: Can.We.Build.It Body: "Are you serious?"

It should be possible to describe it like this in code:

services.AddRabbitMqClient(rabbitMqSection)
                      .AddConsumptionExchange("Bob.The.Builder", exchangeSection)
                      .AddMessageHandlerTransient<CanWeBuildAnythingMessageHandler>("Can.We.Build.#");

Doing so, will indeed create a queue and bind it correctly, but due to the way message handling is done right now, it looks for an exact match in a dictionary... not sure why you don't just create separate consumers but it means that the handler is never called.

antonyvorontsov commented 4 years ago

Hi Keith!

Thank you for the feedback! I really missed that important part. It's kind of embarrassing, but I have never used topic exchanges in projects I've been involved in. It always were direct exchanges. So I just forgot about pattern bindings. I will try to fix it asap.

I am really struggling to find enough free time to make all "backlog" tasks, which you can see in other issues. I will keep you updated on my progress.

Best regards, Antony

antonyvorontsov commented 4 years ago

Keith, hello!

I took some time for me to figure out how make this feature possible and write a code. Initially I added the bug label to this issue, but it wasn't actually a bug, it was a design mistake because I didn't think about such features. So thank you for your great suggestion.

I have just released a new version of the library (v3.1.1). That version provides functionality of pattern matching for message handlers (or wildcard bindings. as you say). I have tried to cover this feature in the documentation, but I will copy-paste an example for other issue-readers.

So now you can register a message handler the same way as before, but using a pattern

services.AddRabbitMqClient(clientConfiguration)
    .AddExchange("ExchangeName", isConsuming: true, exchangeConfiguration)
    .AddMessageHandlerSingleton<CustomMessageHandler>("*.*.*");

Or a set of patterns

services.AddRabbitMqClient(clientConfiguration)
    .AddExchange("ExchangeName", isConsuming: true, exchangeConfiguration)
    .AddMessageHandlerSingleton<CustomMessageHandler>(new[] { "*.*.*", "routing.*.key" });

Or you can get all messages by setting this

services.AddRabbitMqClient(clientConfiguration)
    .AddExchange("ExchangeName", isConsuming: true, exchangeConfiguration)
    .AddMessageHandlerSingleton<CustomMessageHandler>("#");

And so on.

But since wildcard bindings became available you are probably do not want to get extra messages. I mean that the handler registered this way AddMessageHandlerSingleton<CustomMessageHandler>("#") will process all messages regardless of the exchange.

To get messages from the certain exchange you can specify it like this

services.AddRabbitMqClient(clientConfiguration)
    .AddExchange("ExchangeName", isConsuming: true, exchangeConfiguration)
    .AddMessageHandlerSingleton<CustomMessageHandler>("#", "exchange.to.listen.by.message.handler");

So now everything depending on how you register message handlers.

Happy to say that you finally can try it out!

antonyvorontsov commented 4 years ago

Closing this issue due to inactivity

vic10us commented 4 years ago

Awesome work! We are going to try this out in our team next sprint. :) Thank you!