1
votes

I am currently developing a sample project where I use NServiceBus in the back-end to publish events. The back-end is then supposed to be handling its own events through a set of handlers. This works fine when I implement one specific handler for each event like so:

public sealed class MyEventHandler : IHandleMessages<MyEvent> { }

public sealed class OtherEventHandler : IHandleMessages<OtherEvent> { }

However, since these handlers just dispatch the events to another processor, I wanted to clean up a bit and implement only a single generic message handler:

public sealed class GenericHandler : IHandleMessages<object> { }

Unfortunately, the generic handler is only invoked for message types for which another, specific handler is present in the project. In other words, the GenericHandler correctly receives the MyEvent event when I leave the MyEventHandler in the sources, but stops receiving this message when I delete this (now obsolete) handler. My goal is in fact to remove all specific handlers from the project and to work only with a single GenericHandler. Am I missing a basic step in configuration?

The NServiceBus-config looks like this:

<UnicastBusConfig>
  <MessageEndpointMappings>
    <add Assembly="Kingo.Samples.Chess.Api" Endpoint="kingo.samples.chess" />      
  </MessageEndpointMappings>
</UnicastBusConfig>

Furthermore:

  • The Api-assembly mentioned above contains all events that need to be published and handled.
  • I marked all messages with the ICommand and IEvent marker interfaces from NServiceBus.
  • I use NServiceBus V5 (Core) in combination with NServiceBus.Host V6.
  • I have the following custom bus configuration in my EndpointConfig:

    void IConfigureThisEndpoint.Customize(BusConfiguration configuration)
    {                                     
    
        configuration.AssembliesToScan(GetAssembliesToScan("*Chess.Api.dll", "*Chess.dll"));            
        configuration.UsePersistence<InMemoryPersistence>();
        configuration.UseContainer<UnityBuilder>();
        configuration.UseSerialization<JsonSerializer>();
    
        configuration.Conventions().DefiningEventsAs(type => type.Name.EndsWith("Event"));
    }
    
1
I would strongly advise against using a generic handler, this is an anti pattern that will block your ability to properly scale and will introduce coupling... Keep it simple and explicit and have a handler per event...Sean Farmar
@Sean: the reason for wanting to use a single generic handler is because this handler will dispatch the received message to another message processor - which contains/defines separate message handlers for each specific message. The reason I chose this deign is because I mix 'regular' WCF services with NServiceBus and want to use NServiceBus purely as an infrastructural component - not to contain actual business logic or sagas inside its handlers.Wim.van.Gool
cool, did you get it working? did you see my comment below?Sean Farmar
@Sean: no, unfortunately didn't get it working just yet. I feel that it's somehow a limitation (bug?) of NServiceBus, so I resorted to specific message handlers for now, as a (not-so-disasterous) work-around. I saw your comment below, so thanks for that feedback.Wim.van.Gool
maybe open a support case by emailing the details to support at particular.net, mention POC in the title and address it to me, we can have a quick call and try and resolve this?Sean Farmar

1 Answers

0
votes

Your configuration defines an event as any class that ends with "Event". "object" does not meet this criteria, so you won't receive messages in your generic handler because of that.

You would need to use IEvent instead:

public sealed class GenericHandler : IHandleMessages<IEvent> { }