Masstransit EndpointConvention Azure Service Bus

情到浓时终转凉″ 提交于 2020-07-19 18:58:30

问题


I'm wondering if I'm doing something wrong, I expected MassTransit would automatically register ReceiveEndpoints in the EndpointConvention.

Sample code:

services.AddMassTransit(x =>
{
    x.AddServiceBusMessageScheduler();
    x.AddConsumersFromNamespaceContaining<MyNamespace.MyRequestConsumer>();
    x.UsingAzureServiceBus((context, cfg) =>
    {
        // Load the connection string from the configuration.
        cfg.Host(context.GetRequiredService<IConfiguration>().GetValue<string>("ServiceBus:ConnectionString"));
        cfg.UseServiceBusMessageScheduler();

        // Without this line I'm getting an error complaining about no endpoint convention for x could be found.
        EndpointConvention.Map<MyRequest>(new Uri("queue:queue-name"));

        cfg.ReceiveEndpoint("queue-name", e =>
        {
            e.MaxConcurrentCalls = 1;
            e.ConfigureConsumer<MyRequestConsumer>(context);
        });

        cfg.ConfigureEndpoints(context);
    });
});

I thought this line EndpointConvention.Map<MyRequest>(new Uri("queue:queue-name")); wouldn't be necessary to allow sending to the bus without specifing the queue name, or am I missing something?

await bus.Send<MyRequest>(new { ...});


回答1:


The EndpointConvention is a convenience method that allows the use of Send without specifying the endpoint address. There is nothing in MassTransit that will automatically configured this because, frankly, I don't use it. And I don't think anyone else should either. That stated, people do use it for whatever reason.

First, think about the ramifications - if every message type was registered as an endpoint convention, what about messages that are published and consumed on multiple endpoints? That wouldn't work.

So, if you want to route messages by message type, MassTransit has a feature for that. It's called Publish and it works great.

But wait, it's a command, and commands should be Sent.

That is true, however, if you are in control of the application and you know that there is only one consumer in your code base that consumes the KickTheTiresAndLightTheFires message contract, publish is as good as send and you don't need to know the address!

No, seriously dude, I want to use Send!

Okay, fine, here are the details. When using ConfigureEndpoints(), MassTransit uses the IEndpointNameFormatter to generate the receive endpoint queue names based upon the types registered via AddConsumer, AddSagaStateMachine, etc. and that same interface can be used to register your own endpoint conventions if you want to use Send without specifying a destination address.

You are, of course, coupling the knowledge of your consumer and message types, but that's your call. You're already dealing with magic (by using Send without an explicit destination) so why not right?

string queueName = formatter.Consumer<T>()

Use that string for the message types in that consumer as a $"queue:{queueName}" address and register it on the EndpointConvention.

Or, you know, just use Publish.



来源:https://stackoverflow.com/questions/62713786/masstransit-endpointconvention-azure-service-bus

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!