Ninject + "Error loading Ninject component ICache"
Asked Answered
C

3

4

I've just installed the new Ninject.MVC3 from NuGet and trying to make it work in my asp.net mvc 3 app, however I get this weird error now and then when surfing my site:

[InvalidOperationException: Error loading Ninject component ICache
No such component has been registered in the kernel's component container.

Suggestions:
  1) If you have created a custom subclass for KernelBase, ensure that you have properly
     implemented the AddComponents() method.
  2) Ensure that you have not removed the component from the container via a call to RemoveAll().
  3) Ensure you have not accidentally created more than one kernel.
]
   Ninject.Components.ComponentContainer.Get(Type component) in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\Components\ComponentContainer.cs:146
   Ninject.Components.ComponentContainer.Get() in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\Components\ComponentContainer.cs:102
   Ninject.KernelBase.CreateContext(IRequest request, IBinding binding) in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\KernelBase.cs:540
   Ninject.<>c__DisplayClassa.<Resolve>b__6(IBinding binding) in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\KernelBase.cs:375
   System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +20
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
   System.Linq.Enumerable.SingleOrDefault(IEnumerable`1 source) +4178557
   Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:56
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +51

[InvalidOperationException: An error occurred when trying to create a controller of type 'MyApp.Controllers.NewsController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +196
   System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
   System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862580
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

And my code is:

// AppStart_NinjectMVC3.cs

    using System.Web.Mvc;
    using Ninject.Modules;

    [assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.AppStart_NinjectMVC3), "Start")]

    namespace MyApp
    {
        using Microsoft.Web.Infrastructure.DynamicModuleHelper;



  using Ninject;

    public static class AppStart_NinjectMVC3
    {
        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpApplicationModule));
        }
    }
}

// NinjectHttpApplicationModule.cs

using MyApp.Data;
using NHibernate;

namespace MyApp
{
    using System;
    using System.Web;

    using Ninject;
    using Ninject.Web.Mvc;

    public sealed class NinjectHttpApplicationModule : IHttpModule, IDisposable
    {
        #region Ninject Mvc3 extension bootstrapper (Do not touch this code)
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();
        private static bool initialized;
        private static bool kernelDisposed;

        /// <summary>
        /// Initializes a module and prepares it to handle requests.
        /// Do not change this method!
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
        public void Init(HttpApplication context)
        {
            lock (bootstrapper)
            {
                if (initialized)
                {
                    return;
                }

                initialized = true;
                bootstrapper.Initialize(CreateKernel);
            }
        }

        /// <summary>
        /// Disposes the <see cref="T:System.Web.HttpApplication"/> instance.
        /// Do not change this method!
        /// </summary>
        public void Dispose()
        {
            lock (bootstrapper)
            {
                if (kernelDisposed)
                {
                    return;
                }

                kernelDisposed = true;
                bootstrapper.ShutDown();
            }
        }
        #endregion

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            RegisterServices(kernel);
            return kernel;
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<ISession>().ToMethod(x => kernel.Get<SessionFactoryBuilder>().CreateFactory().OpenSession()).InRequestScope();
            kernel.Bind<ITransaction>().ToMethod(x => kernel.Get<ISession>().BeginTransaction()).InRequestScope();
            kernel.Bind(typeof(IRepositoryBase<>)).To(typeof(RepositoryBase<>));
            kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
        }
    }
}

Most of the code is the default one you get when installing by NuGet.. the only thing I've done is to add some bindings to the RegisterServices()

Any suggestions?

Changchun answered 27/2, 2011 at 17:20 Comment(0)
C
6

Fixed in 2.2.1.0

See http://www.planetgeek.ch/2011/03/01/ninject-2-2-1-0-and-ninject-mvc3-2-2-1-0-released/ for more information.

Chapa answered 1/3, 2011 at 20:16 Comment(0)
C
0

Looks like its a bug according to this thread, and that they are working on a fix...

Changchun answered 27/2, 2011 at 17:51 Comment(0)
E
0

Like previously mentioned it does look like a bug.
One option is to simply implement a singleton extension method yourself:

public static class NinjectSingletonExtension
{
    public static CustomSingletonKernelModel<T> SingletonBind<T>(this IKernel i_KernelInstance)
    {
        return new CustomSingletonKernelModel<T>(i_KernelInstance);
    }
}

public class CustomSingletonKernelModel<T>
{
    private const string k_ConstantInjectionName = "Implementation";
    private readonly IKernel _kernel;
    private static object padlock = new Object();

    private T _concreteInstance;


    public CustomSingletonKernelModel(IKernel i_KernelInstance)
    {
        this._kernel = i_KernelInstance;
    }

    public IBindingInNamedWithOrOnSyntax<T> To<TImplement>(TImplement i_Constant = null) where TImplement : class, T
    {
        _kernel.Bind<T>().To<TImplement>().Named(k_ConstantInjectionName);
        var toReturn =
            _kernel.Bind<T>().ToMethod(x =>
                                       {
                                           if (i_Constant != null)
                                           {
                                               return i_Constant;
                                           }

                                           if (_concreteInstance == null)
                                           {
                                               lock (padlock)
                                               {
                                                   if (_concreteInstance == null)
                                                   {
                                                       _concreteInstance = _kernel.Get<T>(k_ConstantInjectionName);
                                                   }
                                               }
                                           }


                                           return _concreteInstance;
                                       }).When(x => true);

        return toReturn;
    }
}

And then simply use:

i_Kernel.SingletonBind<T>().To<TImplement>();

Rather then

i_Kernel.Bind<T>().To<TImplement>().InSingletonScope();
Ectoblast answered 3/4, 2014 at 14:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.