Marconline
Marconline

Reputation: 1451

Ninject + Ninject Child Kernels + Continuous Azure WebJobs

I have an Azure WebJob containing few different functions.

These functions need to be injected with some services by Ninject (using constructor injection). Since the standard JobActivator - the class which is responsible to instantiate jobs' classes - creates them by invoking a parameterless costructor, I cannot use that.

In order to do this, I've created a class implementing the IJobActivator interface - provided by the WebJobs SDK, following something similar to this walkthrough.

Since I need this injected services to be alive until the function completes (and it seems that there is no way for the container to know when a function completes), I followed this workaround: https://blog.tech-fellow.net/2017/04/12/disposable-dependency-for-azure-webjob/

That article refers to a different container (StructureMap), but the concept is the same:

Ninject, as far as I know, doesn't support nested containers, even if I found this extension that seems to do something similar.

So what I would do is:

  1. create a main kernel inside the WebJob, which I pass to the JobActivator
  2. inside the CreateInstance of the JobActivator, I create a new Child Kernel, from the original one
  3. I set that child kernel into the job's class instance
  4. inside the Disposemethod, I will dispose the child kernel

Questions:

Upvotes: 0

Views: 46

Answers (1)

Marconline
Marconline

Reputation: 1451

It turns out that creating a ChildKernel inside the JobActivator Activate() function is a very slow process.

My analysis shows that, if the concurrency on the JobActivator is high, the process of spinning up a new ChildKernel and activate the job will take a considerable amount of time. In my case it was a magnitude of order greater that the real job execution time, so it was totally unceptable.

What I did is serialize the process of job creation inside the JobActivator, by scoping to a particular ExecutionContext (a class that I created) the services that I needed to be scoped to a particular function execution.

All of my jobs implements the IDisposable interface. In the corresponding Dispose() method, I will dispose that particular ExecutionContext, letting Ninject Kernel (the only one instantiated inside the Program.cs) finally release services scoped to that object.

Upvotes: 0

Related Questions