Is it ok to pass Ninject Web.Common UseNinjectMiddleware a lambda which returns a kernel instance?

654 Views Asked by At

Why does UseNinjectMiddleware take a lambda instead of a container instance?

Is it OK to do this?

var container = CreateKernel();
app.UseNinjectMiddleware(() => container);

instead of this:

app.UseNinjectMiddleware(() => CreateKernel);

My container instance in the first snippet is used to resolve dependencies in another part of my app. Does the Ninject Middleware need to be able to create it's own instances which it can modify, muck-around with and re-create at will? If not, I would like to avoid building the dependency tree more than once, hence why I'm wondering if it's OK for the lambda to just return the instance.

1

There are 1 best solutions below

0
qujck On BEST ANSWER

There are a couple of things to note:

The OwinBootstrapper component will load any defined NinjectModule's after calling the passed in Func<IKernel> so you need to take care that you do not load anything twice. see here

The Bootstrapper component calls Dispose on IKernel so you will need to be sure you do not attempt to access the instance after a shutdown has been initiated. see here


You can almost get to the underlying Kernel right after it has been created, maybe you would prefer to raise a PR to make it available?

Currently OwinAppBuilderExtensions defines

public const string NinjectOwinBootstrapperKey = "NinjectOwinBootstrapper";

which it uses to store the run-time instance of OwinBootstrapper

app.Properties.Add(NinjectOwinBootstrapperKey, bootstrapper);

OwinBootstrapper holds a private reference to the run-time instance of the Bootstrapper component and the Bootstrapper instance in turn exposes a reference to the run-time instance of IKernel

public IKernel Kernel
{
    get { return kernelInstance; }
}

So a little PR adding

public IKernel Kernel
{ 
    get
    {
        this.bootstrapper.Kernel;
    }
}

to OwinBootstrapper could make the underlying IKernel available to your code via app.Properties after the call to app.UseNinjectMiddleware(() => container);.