tags:

views:

34

answers:

2

I have no trouble with the concept of publish/subscribe but I cannot get my head around the (auto)configuration.

Scenario

  1. I have a front-end service (F1) which does a SEND of a command message (M1).
  2. This command message is received by a back-end (B1). B1 does some processing and then does a PUBLISH of notification message M2.
  3. Two services (F1 and F2) should receive a this notification message and do their processing/tasks.

[F1] =(M1)=> [B1] =(M2)=> [F1 & F2]

How do F1 and F2 subscribe to notification message M2 which is published/broadcasted by B1?

I cannot find actual configuration in either .config files or code in the samples and I cannot find documentation about this on the NServiceBus webcast.

There is IBus.Subscribe<T> but I cannot see how to subscribe a certain instance. I would expect that I need to supply a queue to which to send the subscribe message to so that I return can receive publishes/announcements.

In short

In short B1 does a PUBLISH of M2.

  1. How can F1 and F2 subscribe to this this message?
  2. How does it work when auto subscribe is not used? So from code or config?
A: 

When you do not auto-subscribe, you have to explicitly subscribe yourself in code. Start by specifying the IWantCustomInitialization interface on your EndpointConfig class. Then you tell NSB to not auto-subscribe:

 NServiceBus.Configure.With()
            .DefaultBuilder()
            .XmlSerializer()
            .MsmqTransport()
            .IsTransactional(true)
            .UnicastBus()
            .DoNotAutoSubscribe()
            .LoadMessageHandlers();

Then within your subscriber endpoint, implement the IWantToRunAtStartup interface. There you can subscribe to specific messages, for example:

#region IWantToRunAtStartup Members

    public void Run()
    {
        this.Bus.Subscribe<IProductUpdatedEvent>();
        this.Bus.Subscribe<IProductCreatedEvent>();
    }

    public void Stop()
    {
        this.Bus.Unsubscribe<IProductUpdatedEvent>();
        this.Bus.Unsubscribe<IProductCreatedEvent>();
    }

    #endregion
Adam Fyles
This makes sense in a environment where I would like for example to monitor service for a specific amount of time during runtime. But in your example you don't target a specific service. So during execution of this code the instance to subscribe to is resolved via the configuration.
Ramon
Yes, the Publisher address is resolved via configuration. If you want to only subscribe to a given Publisher, then specify that in the MessageEndpointMappings as Udi describes. If you want to subscribe to more that one Publisher then add a mapping per publisher.
Adam Fyles
A: 

In the config files of F1 and F2, in the UncastBusConfig section, under the MessageEndpointMappings the following entry:

Then you also need to have a message handler in F1 and F2 for M2. When the bus sees this, it will automatically send the subscription message to the queue of B1, where the bus on the receiving side will store the names of the queues of F1 and F2 as interested in M2.

You probably don't need the .DoNotAutoSubscribe() bit for your scenario.

Udi Dahan
Both F1 and F2 have the required message handlers. So I need to define as many message endpoint mappings as I have publishers? Is that correct? Which in this scenario is just one and this automatically registers the subscribers F1 and F2.
Ramon