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
WebActivatorEx
executing 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?
Looking at the code of
Ninject.Web.Common.Bootstrapper
shows that it stores a single static instance of the kernel, and exposes it via theKernel
property. This means that you can do this inside the OWIN startup method:and you'll have the same
IKernel
instance, complete with whatever bindings you configured inNinjectWebCommon.RegisterServices
Before. You can verify this (as I did) by setting breakpoints in each. More info
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.