20
votes

I have an MVC 5 application which uses Ninject and I am adding Hangfire to it.

When I have added Ninject, I have used the NinjectWebCommon nuget package because of its simplicity in the configuration. So for now Ninject is configured through the NinjectWebCommon class which create a standard kernel and add the bindings.

Moreover I have created some custom module that I load when creating the kernel

private static IKernel CreateKernel() {
    var kernel = new StandardKernel( new MyCustomModule() );
    try {
        kernel.Bind<Func<IKernel>>().ToMethod( ctx => () => new Bootstrapper().Kernel );
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        RegisterServices( kernel );
        return kernel;
    }
    catch {
        kernel.Dispose();
        throw;
    }
}

The Ninject Web Common is registered through the WebActivatorEx class

[assembly: WebActivatorEx.PreApplicationStartMethod( typeof( MyProject.Web.NinjectWebCommon ), "Start" )]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute( typeof( MyProject.Web.NinjectWebCommon ), "Stop" )]

Now the problem is related on how to make Hangfire to see the Ninject configuration. By looking at the Hangfire.Ninject package I can read

The package provides an extension method for IGlobalConfiguration interface:

var kernel = new StandardKernel(); GlobalConfiguration.Configuration.UseNinjectActivator(kernel);

Now my question are:

  • Because of the IGlobalConfiguration interface, I should add the Hangfire Ninject configuration inside the OWIN startup method (where the Hangfire config is already placed). How should I get the current Ninject Kernel (the one that NinjectWebCommon has configured?
  • What about the order of execution? Is the WebActivatorExexecuting before or after the OWIN startup?
  • What happens if I try to execute the configuration twice?

More generally, how can I share the Ninject configuration between the two?

1

1 Answers

12
votes

How should I get the current Ninject Kernel

Looking at the code of Ninject.Web.Common.Bootstrapper shows that it stores a single static instance of the kernel, and exposes it via the Kernel property. This means that you can do this inside the OWIN startup method:

GlobalConfiguration.Configuration.UseNinjectActivator(
                                     new Ninject.Web.Common.Bootstrapper().Kernel);

and you'll have the same IKernel instance, complete with whatever bindings you configured in NinjectWebCommon.RegisterServices

What about the order of execution? Is the WebActivatorEx executing before or after the OWIN startup?

Before. You can verify this (as I did) by setting breakpoints in each. More info

More generally, how can I share the Ninject configuration between the two?

What happens if I try to execute the configuration twice?

The kernel configuration is the "composition root." According to Mark Seemann, a preeminent expert on the subject, there should only be one of these in the application, and it should be as close as possible to the application's entry point.