使用MassTransit无法向Azure Service Bus Topic提交消息
解决MassTransit向Azure Service Bus Topic发消息时的重复实体名错误
错误原因
你遇到的MassTransit.ConfigurationException: The message type Contracts.ClassName entity name was already evaluated: Contracts/ClassName错误,核心原因是同一个消息类型被重复配置了实体名称。你的代码里同时存在两处独立的Bus配置逻辑:
- 通过
services.AddMassTransit注册了一个Bus实例 - 又通过
Bus.Factory.CreateUsingAzureServiceBus手动创建了另一个Bus实例,并且再次为ClassName设置了实体名
MassTransit会全局追踪消息类型的配置信息,重复配置就会触发这个异常。
修复方案
1. 统一Bus配置到DI注册流程
把消息实体名称的配置移到AddMassTransit的注册代码里,删除手动创建Bus的逻辑:
services.AddMassTransit(x => { x.AddConsumer<TestConsumer>(); // 在这里统一配置消息对应的Topic名称 x.Message<ClassName>(cfg => { cfg.SetEntityName("topicName"); }); x.UsingAzureServiceBus((ctx, cfg) => { cfg.ClearMessageDeserializers(); cfg.UseRawJsonSerializer(); cfg.Host(_busConfiguration.ServiceBus.ConnectionString); cfg.ReceiveEndpoint(_busConfiguration.ServiceBus.QueueName, ec => { ec.ConfigureConsumeTopology = false; ctx.ConfigureConsumer<TestConsumer>(ec); // 配置消费者订阅指定Topic(替换为你的实际订阅名称) ec.Subscribe<ClassName>("your-subscription-name"); }); }); });
2. 通过DI注入发送消息
不再手动创建Bus,而是通过依赖注入获取IPublishEndpoint或IBus来发送消息:
// 在类的构造函数中注入IPublishEndpoint private readonly IPublishEndpoint _publishEndpoint; private readonly ILogger _logger; public YourService(IPublishEndpoint publishEndpoint, ILogger<YourService> logger) { _publishEndpoint = publishEndpoint; _logger = logger; } // 发送消息的方法 public async Task SendTopicMessage(string status, string user) { try { await _publishEndpoint.Publish(new ClassName { Status = status, User = user }); _logger.LogInformation($"Topic Message Sent Successfully."); } catch (Exception ex) { _logger.LogError($"Failed to Send Message!\n{ex.Message} to Topic"); } }
关键注意事项
- 整个应用中只保留一处MassTransit Bus的注册,禁止手动创建多个独立Bus实例。
- 消息类型的实体名称配置必须唯一,统一放在
AddMassTransit的配置流程中。 - 消费者端如果需要从Topic接收消息,必须在
ReceiveEndpoint里通过Subscribe方法配置对应的订阅名称。
内容的提问来源于stack exchange,提问作者KJSR
相关产品推荐
相关产品推荐

