2

I use Rebus 3.0.1 with Simpleinjector. I have registered a decorator, for logging, of all the handlers, this way:

container.RegisterDecorator(typeof(IHandleMessages<>), typeof(HandlerLogDecorator<>));


Everything works fine, except the Sagas: because, in LoadSagaDataStep, the following code

            var handlerInvokersForSagas = context.Load<HandlerInvokers>()
            .Where(l => l.HasSaga)
            .ToList();

is not able to find the Saga under the covers.
If I unregister the decorators, saga starts working again.

Any suggestion to conciliate sagas and handlers decorators?

ilcorvo
  • 446
  • 5
  • 18

1 Answers1

2

Unfortunately, as you have discovered, Rebus does not expect handlers (including sagas) to be wrapped in decorators.

It uses decorators a lot for various things internally, and it encourages the use of decorators as an extension point for developers, but that only goes for all of Rebus' services like IPipeline, ISubscriptionStorage, etc.

If you want to log stuff in relation to message handling, a better extension point would be to either

a) use Rebus.Events and simply install an event handler like this:

Configure.With(...)
    .(...)
    .Events(e => {
        e.AfterMessageHandled += (bus, headers, message, context, args) => {
            // log stuff in here :)
        };
    })
    .Start();

or

b) create an incoming pipeline step that logs what you want to log like this:

Configure.With(...)
    .(...)
    .Options(o => {
        o.Decorate<IPipeline>(c => {
            var step = new YourLoggingStep();
            var pipeline = c.Get<IPipeline>();

            return new PipelineStepInjector(pipeline)
                .OnReceive(step, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep));
        });
    })
    .Start();

probably wrapping all of the ugly stuff in an extension method that makes usage look more like this:

Configure.With(...)
    .(...)
    .Options(o => {
        o.LogHandledMessages();
    })
    .Start();
mookid8000
  • 18,258
  • 2
  • 39
  • 63
  • Sorry I thought the answer solved the problem but it does not. Now that I was going to put my hands on it, I noticed that decorating the pipeline is not the same as decorating the handlers. In fact, you can not decorate the single execution of `await invoker.Invoke ();` but the execution of the list of `HandlerInvokers` (what Rebus already does). Any suggestions? – ilcorvo Sep 27 '17 at 08:49
  • Extrema ratio would be to replace `DispatchIncomingMessageStep` in the pipeline, but I dislike it because `DispatchIncomingMessageStep` is a core part of the framework. – ilcorvo Sep 27 '17 at 08:56