Ninject + "Ошибка загрузки Ninject компонента ICache" - PullRequest
4 голосов
/ 27 февраля 2011

Я только что установил новый Ninject.MVC3 от NuGet и пытаюсь заставить его работать в моем приложении asp.net mvc 3, однако я иногда получаю эту странную ошибку при просмотре моего сайта:

[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

И мой код:

// 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>();
        }
    }
}

Большая часть кода является кодом по умолчаниювы получаете при установке NuGet ... единственное, что я сделал, это добавил некоторые привязки к RegisterServices()

Есть предложения?

Ответы [ 3 ]

6 голосов
/ 01 марта 2011

Исправлено в 2.2.1.0

См. http://www.planetgeek.ch/2011/03/01/ninject-2-2-1-0-and-ninject-mvc3-2-2-1-0-released/ для получения дополнительной информации.

0 голосов
/ 03 апреля 2014

Как упоминалось ранее, это похоже на ошибку.Один из вариантов - просто реализовать метод одноэлементного расширения:

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;
    }
}

, а затем просто использовать:

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

Вместо

i_Kernel.Bind<T>().To<TImplement>().InSingletonScope();
0 голосов
/ 27 февраля 2011

Похоже, это ошибка согласно этой ветке, и что они работают над исправлением ...

...