Autosubscribe peculiarities


(Nathan Richards) #1

Looking for clarification on the autosubscribe behavior.

Was having issues with subscription messages not being sent. I was using a single event handler that handles an abstract super-class of multiple events. The subscription documentation here didn’t seem to help:

I eventually found the answer here:!searchin/particularsoftware/autosubscribe|sort:relevance/particularsoftware/Fcnn5gtdE9Q/3FiY3NxM2LcJ

The autosubscribe feature that NServiceBus has out of the box only automatically subscribes if there are handlers for the specific message types

I can fix the issue by explicitly subscribing to each message type after the endpoint has started.

What I’m still confused about though is that, without explicitly subscribing, instead of getting no subscription messages at all I got a single subscription message for one of the specific events, which is a sub-class of the type I handle. Does anyone know why that is?

(Tim Bussmann) #2

Hey Nathan,

To help me understand your scenario better, can you tell me which version of NServiceBus and which transport you’re using? We’ve made several changes around routing and message driven publish/subscribe in v6 which relate to message hierachies.

Do you specify your routing information via the MessageEndpointMappings section in the config file or via code first API?

(Nathan Richards) #3

Hi Tim,

We’re using NServiceBus 6 (v6.3.4 at the time of writing), with MSMQ Transport (no DTC) and SQL Persistence.

I’m using the code-first API, namely this method:

RoutingSettings<MsmqTransport>.RegisterPublisher(Type eventType, string publisherEndpoint)

I call this method for every IEvent type I want to subscribe to. We use an instance mapping file for physical routing.

(Tim Bussmann) #4

Hey Nathan,

I still struggle to fully understand the behavior you’re describing. Let me try to recapture how I understood your setup:

  • You have a Subscriber endpoint which has a handler for BaseMessage : IEvent and you register a publisher using RegisterPublisher(typeof(BaseMessage), <PublisherAddress>) and which uses autosubscribe (no explicit calls to Subscribe).
  • You have Publisher endpoint which publishes a ChildMessage which inherits from BaseMessage.

In this case, you described that Publisher receives a subscription message for ChildMessage.

Did I understand that correctly?

(Nathan Richards) #5

Hi Tim,

Sorry for the delay in replying.

We have a hierarchy of events, which all ultimately inherit from a single base class which implements the IEvent interface). These events are published by a single logical endpoint.

There is a single Event Handler on the receive that handles the base class type messages.

Below is a simplified example:

public abstract class BaseEvent : IEvent {...}
public class EventA : BaseEvent {...}
public class EventB : BaseEvent {...}
public class EventC : BaseEvent {...}

public class BaseEventHandler : IHandleMessages<BaseEvent> {...}

If I avoid explicit subscribes (auto-subscribe only), I observe that a single subscription message is sent to the publisher for one of the concrete event types (e.g. EventA in my example).

This is surprising as I’d expect to see either no subscribe messages, or three (one for each concrete event type).

(Tim Bussmann) #6

Hey Nathan,

Thanks for the example. The behavior you described sounds surprising to me as well. I’ve tried to reproduce it by using our basic publish/subscribe sample using the message types and handler you posted.Additionally I switched transport to MSMQ and persistence to InMemoryPersistence for everything to work and then registered the publisher using routing.RegisterPublisher(typeof(BaseEvent), "Samples.PubSub.Publisher");. When I start the subscriber, I can see one subscription message in the publisher queue, but that subscription message is using the BaseEvent type as expected. I was not able to reproduce the behavior you’re describing with the information you mentioned so far.

Can you try whether you manage to reproduce the described behavior using the same sample from our docs page or can you share another solution with me which shows the incorrect subscription message?

Notice that with v6, there is no inheritance on routing information. If you handle BaseEvent, you’ll need to register the publisher for this type. If you register your publisher for the actual type it’s publishing (e.g. EventA), you need to explicitly call Subscribe<EventA>() when starting the endpoint.

Also note that even when subscribing to events of type BaseEvent, the actual message received by the subscriber will be of the concrete type, e.g. EventA if the publisher publishes EventA. This EventA message will of course be correctly handled by the BaseEvent message handler.