The IBM MQ transport implements publish/subscribe messaging using IBM MQ's native topic and subscription infrastructure. Event subscriptions do not require NServiceBus persistence.
Topology
The transport uses one IBM MQ topic per concrete event type. When an event is published, the message is sent to the corresponding topic. Subscribers create durable subscriptions against the topic, with messages delivered to their input queue.
Sending (unicast)
Commands are sent directly to the destination queue by name. No topics are involved.
Publishing (multicast)
When an endpoint publishes an event, the message is published to the topic for that event type. IBM MQ delivers a copy to every endpoint with a durable subscription on that topic.
Subscribing
When an endpoint subscribes to an event type, the transport creates a durable subscription linking the event's topic to the endpoint's input queue. When the endpoint starts, existing subscriptions are resumed automatically.
Unsubscribing
When an endpoint unsubscribes from an event type, the durable subscription is deleted from the queue manager.
IBM MQ resources
The transport uses three types of IBM MQ resources:
Queues
Local queues (QLOCAL) are used for point-to-point messaging (commands) and as the destination for durable subscriptions (events). Each endpoint has an input queue named after the endpoint.
Topic objects
An administrative topic object defines the mapping between a topic name (the admin object identifier, max 48 characters) and a topic string (the routing path used by publishers and subscribers). For example:
| Property | Example |
|---|---|
| Topic name (admin object) | DEV. |
| Topic string | dev/ |
Publishers open the topic by its topic string to publish messages. The admin object must exist on the queue manager before publishing.
Subscriptions
A durable subscription links a topic string to a destination queue. When a message is published to a matching topic string, IBM MQ delivers a copy to the subscription's destination queue. Subscription names follow the format EndpointName:topicstring/, for example:
OrderService:dev/myapp.events.orderplaced/
Resource creation
When installers are enabled
When EnableInstallers() is called, the transport creates resources during endpoint startup:
| Resource | Created by | When |
|---|---|---|
| Input queue | Both publisher and subscriber | At startup, for the endpoint's own queue |
| Error queue | Both publisher and subscriber | At startup |
| Send destination queues | Sender | At startup, for all configured send-only destinations |
| Topic objects | Publisher or subscriber | At startup, for all explicitly configured PublishTo and SubscribeTo topic routes |
| Durable subscriptions | Subscriber | At subscribe time, when the endpoint subscribes to an event type |
When installers are not enabled
The transport validates that all explicitly configured topics exist on the queue manager. If any are missing, startup fails with an InvalidOperationException listing the missing topics. Queues and subscriptions must be pre-created using the command-line tool or native IBM MQ administration.
See security and permissions for the IBM MQ authorities required for each operation.
Polymorphism
IBM MQ uses a topic-per-event model: each concrete event type is published to its own topic. Subscribing to a base class or interface does not automatically subscribe to topics for derived types. Without explicit configuration, a handler for IOrderEvent would only receive messages published directly to the IOrderEvent topic, missing messages published as OrderPlaced or OrderCancelled.
To prevent accidental under-subscription, the transport throws an InvalidOperationException at startup when subscribing to a type that has known descendants in the loaded assemblies. This guard is controlled by ThrowOnPolymorphicSubscription (default: true).
Explicit subscription routing
Use SubscribeTo to map a subscribed event type to the concrete types' topics that should be received:
var transport = new IBMMQTransport
{
// ... connection settings ...
};
// Subscribe to OrderPlaced and all known concrete types
transport.Topology.SubscribeTo<IOrderEvent, OrderPlaced>();
transport.Topology.SubscribeTo<IOrderEvent, ExpressOrderPlaced>();
This creates subscriptions on both the OrderPlaced and ExpressOrderPlaced topics, delivering both to the subscriber's input queue:
Alternatively, specify topic strings directly when they don't follow the naming convention:
var transport = new IBMMQTransport
{
// ... connection settings ...
};
// Subscribe using explicit topic strings
transport.Topology.SubscribeTo<IOrderEvent>("prod/mycompany.events.orderplaced/");
transport.Topology.SubscribeTo<IOrderEvent>("prod/mycompany.events.expressorderplaced/");
Explicit publish routing
Use PublishTo to override the topic for a published event type. This is useful when integrating with existing topic structures:
var transport = new IBMMQTransport
{
// ... connection settings ...
};
// Override the default topic for a published event type
transport.Topology.PublishTo<OrderPlaced>("legacy/order/events/");
// When the admin object name can't be derived from the topic string
transport.Topology.PublishTo<OrderPlaced>("LEGACY.ORDER.EVENTS", "legacy/order/events/");
Disabling the polymorphic subscription guard
If a subscriber intentionally subscribes to only one type's topic (without receiving descendants), disable the guard:
var transport = new IBMMQTransport
{
// ... connection settings ...
};
// Disable the guard that throws when subscribing to a type with descendants
transport.Topology.ThrowOnPolymorphicSubscription = false;
Disabling this guard means subscribing to a base type will silently create a subscription only for that exact type's topic. Messages published as derived types will not be received unless explicit routes are configured.
Deployment recommendations for polymorphic event hierarchies
When using polymorphic events, distribute event types in dedicated, independently versioned packages. This allows subscribers to reference new concrete types and update their subscriptions before the publisher begins publishing those events.
Ensure that the deployment pipeline runs all subscriber subscription steps before starting the new version of the publisher. If a publisher starts publishing a new concrete event type before subscribers have created their subscriptions, those messages will be lost because no durable subscription exists to route them to a queue.
A typical deployment order:
- Deploy the updated message contracts package containing the new event type.
- Update subscriber endpoint configurations to add
SubscribeToroutes for the new type. - Run the command-line tool to create subscriptions for all subscribers, or deploy and start all subscribing endpoints so they create their durable subscriptions.
- Deploy and start the publishing endpoint.
Topic naming
Topics are named using a configurable strategy. The prefix defaults to DEV and the fully qualified type name determines the rest:
| Concept | Example |
|---|---|
| Topic name | DEV. |
| Topic string | dev/ |
| Subscription name | OrderService:dev/ |
IBM MQ topic names are limited to 48 characters. If the generated name exceeds this limit, the transport throws an exception at startup. See topic naming configuration for how to customize the naming strategy.