-
Notifications
You must be signed in to change notification settings - Fork 20
Description
When using topology.PublishTo<TEvent>("SharedTopic") to multiplex multiple concrete event types through a single topic, the transport currently has no awareness of this multiplexing at install time. Users must manually provision subscription rules correlation filters) via IaC or the ServiceBusAdministrationClient for both the publishing side (stamping the concrete type) and the subscribing side (filtering to only the desired type).
It would be a significant improvement if the transport could detect this multiplexing pattern and automatically provision sensible correlation filter rules on both sides when endpoint installers are enabled — but this should be an explicit opt-in, not a default behaviour.
Motivation
A common use case for topic multiplexing is polymorphic event hierarchies where:
- A base event type (e.g.
ProductOrdered) is a stable contract in its own assembly - Concrete derived types (e.g.
CarInsuranceProductOrdered) are published to the shared base topic viaPublishTo<TConcrete>("ProductOrdered") - Two kinds of subscribers exist:
- Endpoints handling only a specific concrete type — these need a correlation
filter to avoid receiving all events on that topic - Endpoints handling the base type — these want everything on the topic and need
a catch-all (no filter) subscription
- Endpoints handling only a specific concrete type — these need a correlation
Without automatic provisioning, users must step outside the NServiceBus installer pipeline to configure these rules, splitting infrastructure concerns across multiple tools and creating a sharp edge when onboarding new event types.
Context
Topic multiplexing and polymorphic routing are advanced, deliberate topology choices. The recommended default for most systems remains topic-per-event, which avoids filtering complexity entirely and maps cleanly to NServiceBus's event model.
Any installer support for correlation filters should therefore be:
- Explicitly opted into via topology configuration, not inferred automatically from the presence of
PublishTooverrides - Clearly documented as an advanced scenario with guidance on when it is and isn't appropriate
- Not a replacement for the auto-forwarding pattern, which remains the better fit when subscribers cannot reference concrete types at all
The goal is to reduce friction for teams who have consciously chosen multiplexing, not to make multiplexing feel like a first-class default path.
Possible Behaviour
Publish side
When an event is published to a shared/multiplexed topic, the transport should consistently stamp a well-known broker property with the concrete CLR type name (e.g. a dedicated application property). This should happen automatically when multiplexing is opted into, without requiring users to wire up OutgoingNativeMessageCustomization manually.
Subscribe side
When installers are enabled and the endpoint has opted into multiplexed subscription support, the transport should inspect IHandleMessages<T> registrations and:
-
Concrete type handler (e.g.
IHandleMessages<CarInsuranceProductOrdered>):
Provision aCorrelationFilteron the subscription scoped to that concrete type's fully-qualified name, so the endpoint only receives matching events. -
Base/shared type handler (e.g.
IHandleMessages<ProductOrdered>):
Provision a catch-all subscription with no filter, receiving all events on the shared topic. -
Mixed handlers (endpoint handles both base and one or more concrete types):
This is an edge case worth explicitly calling out — the transport should either warn or default to the catch-all strategy, since a correlation filter would inadvertently drop messages the endpoint is supposed to handle.
Constraints
- Behaviour only activates when both installers are enabled and the user has explicitly opted in — zero change in behaviour for the default topic-per-event path
- A clear, documented convention is needed for which broker property carries the concrete type name — ideally reusing something already present on NServiceBus messages (e.g.
NServiceBus.EnclosedMessageTypes) to avoid inventing a new convention - Users managing subscription rules entirely via IaC should be able to opt out, even when using multiplexing
References
- Topic-per-event topology docs
- Stack Overflow discussion — raised by a user migrating from NSB 8 to NSB 10 who hit exactly this gap