We are wanting to use MassTransit with Azure Service Bus across different Azure web apps. To keep with an existing pattern, we want to define consumers and the messages they respond to by the message type. If two message types have the same members, it seems all the consumers that are registered with a type with the same members is triggered.
eg Consume(ConsumeContext<OrderCancelled> context)
and Consume(ConsumeContext<OrderCreated> context)
where the classes are both:
public record OrderCancelled(int OrderId, DateTime Date)
and
public record OrderCreated(int OrderId, DateTime Date)
I have done something along these lines, and when one of those messages is published on the Azure Service Bus topic that these consumers subscribe to, both of the consumers are called. I've noticed that MassTransit adds a custom field to the message:
MT-MessageType: urn:message:Business.Messages.Events:OrderCancelled
So it does have some way of knowing which type was used to send the message, even if the context.Message
is deserialized JSON. (This MT-MessageType is available in context.ReceiveContext.TransportHeaders
).
Is there a configuration to ensure just the intended consumer responds to a message of the given type?
Thanks, Paul
MassTransit will only deliver messages to consumers that match the message type (including both the namespace and message type name).
The only exception to this rule is when using the RAW JSON message deserializer with the default options. Originally, the RAW JSON message deserializer was built to support consuming messages from external (non-MassTransit) applications that don't specify a message type. Which means the default options for the RAW JSON deserializer will dispatch the message to all consumers, as no message type check is performed.
To use RAW JSON between MassTransit applications, additional options must be specified:
cfg.UseRawJsonSerializer(RawSerializerOptions.AddTransportHeaders | RawSerializerOptions.CopyHeaders);
This is straight out of the documentation.