Reputation: 1451
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:
JobActivator
a nested container is createdIDisposable
interfaceDispose()
method that child container is disposedNinject, 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:
JobActivator
CreateInstance
of the JobActivator
, I create a new Child Kernel, from the original oneDispose
method, I will dispose the child kernelQuestions:
Dispose
method of the child kernel. Am I correct if I say that by calling Dispose()
on the child kernel, wont' dispose the main one?Dispose()
method), then all the created instances - even those that are InTransientScope - will be disposed?Upvotes: 0
Views: 46
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