Masstransit EndpointConvention Azure Service Bus



>我想知道我是否做错了什么,我希望MassTransit会自动在EndpointConvention中注册ReceiveEndpoints

示例代码:

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);
});
});

我认为这行EndpointConvention.Map<MyRequest>(new Uri("queue:queue-name"));没有必要允许在不指定队列名称的情况下发送到总线,还是我错过了什么?

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

EndpointConvention是一种方便的方法,允许在不指定终结点地址的情况下使用Send。MassTransit 中没有任何内容会自动配置它,因为坦率地说,我不使用它。我认为其他人也不应该这样做。也就是说,无论出于何种原因,人们都会使用它。

首先,考虑后果 - 如果每个消息类型都注册为终结点约定,那么在多个终结点上发布和使用的消息呢?那行不通。

因此,如果您想按消息类型路由消息,MassTransit 具有该功能。它被称为Publish,效果很好。

但是等等,这是一个命令,命令应该是发送的

但是,如果您控制应用程序,并且知道代码库中只有一个使用者使用KickTheTiresAndLightTheFires消息协定,则发布与发送一样好,并且您不需要知道地址!

不,说真的,伙计,我想使用发送!

好的,好的,这是细节。使用 ConfigureEndpoints(( 时,MassTransit 使用IEndpointNameFormatter根据通过AddConsumerAddSagaStateMachine等注册的类型生成接收端点队列名称,如果要在不指定目标地址的情况下使用End,则可以使用相同的接口来注册您自己的端点约定。

当然,您正在耦合消费者和消息类型的知识,但这是您的决定。您已经在处理魔法(通过使用没有明确目的地的发送(,那么为什么不对呢?

string queueName = formatter.Consumer<T>()

将该字符串用于该使用者中的消息类型作为$"queue:{queueName}"地址,并将其注册到 EndpointConvention。

或者,你知道,只是使用Publish.

最新更新