MessageHandler Scoped Dependency

Hi,

I have a Policy Saga that is orchestrating worker scheduling. It uses Send/Reply to load some data from a couple different services and then runs some logic to auto generate a schedule based on the inputs. At the end it publishes/sends out the changes to the schedule based on the inputs.

The ScheduleBuilder logic is somewhat involved and is broken down among a number of child classes.

I am trying to build a “logger” that can record information on what is happening inside of the ScheduleBuilder and its dependent classes.

In a perfect world I would like to create a Message Handler scoped Dependency injected class named IScheduleLogger that could be injected and used to capture trace info about the various steps in the workflow.

At the end of the processing I would take what was collected by the logger and drop that into the SagaData and, at the end of the operation, after it publishes out the necessary task assignment/shift change events, publish a final message that would contain the trace info and related log. (this would be configurable and only enabled for troubleshooting)

I could then save that to a log store (probably a DB to start). Doing this, I can pull down that state and rerun the policy exactly on my local machine to troubleshoot any problems with the complex logic.

If I cannot get an Dependency Injection approach working I CAN just pass a SchedulingState object all the way down and all the way back up and use that to capture the logged state info, but… I don’t much like that approach.

Is there a way in NServiceBus to create the equivalent of the webapi InstancePerRequest type dependency injection that would live for the life of the MessageHandler? Or would I just need to pass my “context” all the way down and all the way back up?

Ok, Nevermind… I figured it out… I’m using Autofac for Dependency Injection and had only been looking through the Autofac documentation…

When I looked more deeply in the core DI documentation I found this:

which led me to the autofac equivalent:

so, it seems that just configuring my autofac DI as follows:

builder.RegisterType().As().InstancePerLifetimeScope();

will solve my problem and will allow me to do DI scoped to a single transport message.

Thanks!

Hi Max,

Like you mentioned, you can use the PerLifetimeScope to register dependencies that are “singletons” for the lifetime of a message being handled. NServiceBus creates a child container per message received.

I have also seen people using “ambient state” like AsyncLocals for such a purpose. While this is a very hidden and magic approach, one of the benefits it could bring is that it is possible to automatically attach certain types of header information to outgoing messages within the message handling pipeline based on the presence of that “ambient state”.

Here is a conversation on github that goes a bit in depth into that space

Regards
Daniel