1

I'm having some trouble with my handlers not "catching" my events. My current structure is that I have a wrapper around Rebus in a separate package that wraps around Rebus' methods and expose a factory to use with i.e. Autofac - so far so good.

I then have all my domain events in separate packages and namespaces so they don't know about Rebus and vice versa. he all derive from the type IDistributedEvent and implements the abstract type DistributedEvent.

When I publish an event, say MessageSent, I then in my wrapper make an envelope event BusEvent where I set the domain event as a Payload property:

public Task Publish<T>( T payload, TimeSpan expiration ) where T : IDistributedEvent
{
    var message = new BusEvent<T> { Payload = payload };
    return InternalBus.Publish( message, new Dictionary<string, string> {
        { Headers.TimeToBeReceived, expiration.ToString() },
        { "pd-version", payload.EventVersion.ToString() },
    } );
}

The reason for this is to be able to add some metadata over time (But maybe this is the wrong way of doing this).

Anyway, my problem is now that my handlers is no recognised as a handler that can handle the type BusEvent<MessageSent>, even though I create handlers using the interface IHandleMessages<BusEvent<T>> where T : IDistributedEvent

So the question is: Am I doing it wrong here, or is this simply just a bad way of doing it. Thus, I should just remove the enveloping type and handle the domain event type directly?

Hulvej
  • 3,895
  • 1
  • 18
  • 21
  • Can you please share wrapper you have implemented for IDistributedEvent , it would be good help to me as I am trying to achieve something similar. Thanks. – PradipB Mar 26 '20 at 15:53

1 Answers1

0

If I were you, I would ditch the envelope thing – Rebus already has a mechanism in place that allows for attaching headers to messages when you send them, so you can add custom things already if you like.

The limitation of course is that your extra data needs to be representable as string-string key-value pairs, but then again: JSON is a string, so anything is possible ;)

I don't see any reason though why it should not work with your homemade generic envelope – if your handlers are registered as the correct IHandleMessages<BusEvent<YourMessage>> when the sent message is a YourMessage, it should work just fine.

Is it because you expect the polymorphic dispatch to work with a generic handler implementing IHandleMessages<BusEvent<T>> where T : IDistributedEvent? Because then it won't work, because receiving a message of the type BusEvent<MessageSent> would result in looking up the following handlers in Autofac:

IHandleMessages<BusEvent<MessageSent>>
IHandleMessages<object>

because that's what Rebus finds when it looks up the inheritance chain starting with BusEvent<>, but obviously that does not include

IHandleMessages<BusEvent<DistributedEvent>>

or

IHandleMessages<BusEvent<IDistributedEvent>>
mookid8000
  • 18,258
  • 2
  • 39
  • 63
  • I decided to ditch `BusEvent` and that obviously made it simpler. However, I can still not get the polymorphic dispatch to work. I have a handler that implements `IHandleMessages` on a bus instance that have subscribed to `IDistributedEvent` – Hulvej Feb 14 '17 at 13:15
  • Is the handler type registered in the container in such a way that it is returned when resolving IHandleMessages? – mookid8000 Feb 14 '17 at 13:29
  • another thing: you still need to subscribe to `SomeEvent` or whatever the concrete type is – when Rebus publishes a message it infers a topic from the message type, which by default is the (simple) assembly-qualified type name, e.g. something like `MyMessages.SomeEvent, MyMessages` – mookid8000 Feb 14 '17 at 13:33
  • yes: `.Register( ( ctx ) => new CatchAllHandler { Name = name } );` I'm using the `BuiltinHandlerActivator` for now – Hulvej Feb 14 '17 at 13:34
  • It seems like the subscriptions doesn't work the way I would have excepted. I should mention the full namespaces that I use: `MyCompany.Events.Abstractions.DistributedEvent` in the handler (and the subscription. `MyCompany.Events.Distributed.Domain.Messaging.MessageSent : MyCompany.Events.Abstractions.DistributedEvent` is the type being published. – Hulvej Feb 14 '17 at 13:38
  • Im gonna accept this answer, because ditching the envelope of cause fixed the issue with the *handler* being able to handle all derived types of the registred type. About the subscription, it properly another question – Hulvej Feb 15 '17 at 07:58
  • Sry for the confusion. I totally missed your comment here http://stackoverflow.com/questions/42203343/rebus-how-to-handle-event-types-with-generics/42208144?noredirect=1#comment71614475_42208144. – Hulvej Feb 15 '17 at 11:12