Question

I am trying to use Bootstrapper with Ninject. I have installed Ninject.MVC3 to initialize my Ninject container from nuget and I have created a test module like this:

public class TestNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<DBEntities>().ToSelf().InRequestScope();
        Bind(typeof(IGenericRepository<>))
              .To(typeof(GenericRepository<>)).InRequestScope();
        Bind<ISystemRepository>().To<SystemRepository>().InRequestScope();
        Bind<IUnitOfWork>().To<UnitOfWork>();
    }
}

I have also included the Start() call in my Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        Bootstrapper.With.Ninject().Start();
        Bootstrapper.With.AutoMapper().Start();
    }
}

However I still get an ActivationException from Ninject when a controller with dependency is called, signalling my TestNinjectModule.Load() method was not called. How can I solve that?

Exception Message:

Error activating IUnitOfWork No matching bindings are available, and the type is not self-bindable. Activation path: 2) Injection of dependency IUnitOfWork into parameter unitOfWork of constructor of type > TreasurySystemController 1) Request for SystemController

Suggestions: 1) Ensure that you have defined a binding for IUnitOfWork. 2) If the binding was defined in a module, ensure that the module has been loaded into > the kernel. 3) Ensure you have not accidentally created more than one kernel. 4) If you are using constructor arguments, ensure that the parameter name matches the >constructors parameter name. 5) If you are using automatic module loading, ensure the search path and filters are >correct.

Stack Trace:

at Ninject.KernelBase.Resolve(IRequest request) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 359 at Ninject.Planning.Targets.Target1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197 at Ninject.Planning.Targets.Target1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165 at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114 at Ninject.Activation.Providers.StandardProvider.<>c_DisplayClass4.b_2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157 at Ninject.KernelBase.<>c_DisplayClass10.b_c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386 at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable1 source) at Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:line 56 at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)

Was it helpful?

Solution

I have found a solution. By changing the implementation of NinjectWebCommon to:

public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();
    public static IKernel Kernel { get; private set; } // Expose the kernel through a property

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        return Kernel = kernel;
    }
}

Then in Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        Bootstrapper.With.AutoMapper().Start();
        Bootstrapper.With.Ninject()
            .WithContainer(NinjectWebCommon.Kernel) // Use the kernel inside NinjectWebCommon instead of creating a new one
            .Start();
    }
}

Then all classes deriving from NinjectModule will have their Load() methods called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top