Ninject w ASP.NET MVC4

Więc po wielu przykręceniach w końcu dostałem Ninject połączony i skompilowany w mojej aplikacji MVC4. Problem, w którym byłem uruchomiony, to interfejs IDependencyScope, który już nie istnieje, z powodu tego, co mogę powiedzieć, a przestrzeń nazw System.Web.Http.Dependencies została usunięta.

Więc mój problem jest taki, że mam wszystko podłączone i po uruchomieniu aplikacji otrzymuję:

    Sequence contains no elements

    [InvalidOperationException: Sequence contains no elements]
   System.Linq.Enumerable.Single(IEnumerable`1 source) +379
   Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin.Start() in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectMvcHttpApplicationPlugin.cs:53
   Ninject.Web.Common.Bootstrapper.<Initialize>b__0(INinjectHttpApplicationPlugin c) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:52
   Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:31
   Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:53
   Ninject.Web.Common.NinjectHttpApplication.Application_Start() in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\NinjectHttpApplication.cs:81

Którego nie udało mi się wytropić, a nawet nie mogę pojąć, skąd pochodzi.

Moje standardowe metody Ninject w Global.asax.cs wyglądają następująco:

        protected override IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            kernel.Bind<IRenderHelper>().To<RenderHelper>();

            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
            return kernel;
        }

        protected override void OnApplicationStarted()
        {
            base.OnApplicationStarted();
            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
            BundleTable.Bundles.RegisterTemplateBundles();
        }

I mój niestandardowy przelicznik:

public class NinjectDependencyResolver : IDependencyResolver
{
    private readonly IKernel _kernel;

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
     {
         return _kernel.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
         try
         {
             return _kernel.GetAll(serviceType);
         }
         catch (Exception)
         {
             return new List<object>();
         }
     }

     public void Dispose()
     {
         // When BeginScope returns 'this', the Dispose method must be a no-op.
     }
}

Każdy wgląd tutaj byłby bardzo mile widziany. Spędziłem już zbyt wiele czasu, próbując podłączyć dowolną strukturę DI do najnowszego MVC4 RC działającego na platformie .NET 4.5, a teraz osiągnąłem poziom tolerancji dla rzeczy, które po prostu nie działają.

Edytuj # 1 Trochę dalszych badań w githubie ExtensionsForIEnumerableOfT.cs niewiele pomaga:

https://github.com/ninject/ninject/blob/master/src/Ninject/Infrastructure/Language/ExtensionsForIEnumerableOfT.cs

I być może, gdybym sam to napisał, zacząłbym to rozumieć, ale Bootstrapper.cs też nie pomaga.

https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs

Mam nadzieję, że te szczegóły ułatwią każdemu z was, kto może mieć więcej doświadczenia z Ninject.

Edytuj # 2 Wystąpił błąd szczególnie w NinjectMvcHttpApplicationPlugin.cs:

Linia obrażająca to:

ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());

Który żyje w następujący sposób:

public void Start()
{
    ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
    DependencyResolver.SetResolver(this.CreateDependencyResolver());
    RemoveDefaultAttributeFilterProvider();
}

Kolekcja ModelValidatorProviders zawiera 2 elementy: {System.Web.Mvc.DataErrorInfoModelValidatorProvider} {System.Web.Mvc.ClientDataTypeModelValidatorProvider}

I próbuje usunąć pojedyncze wystąpienie:

System.Web.Mvc.DataAnnotationsModelValidatorProvider

Który najwyraźniej nie jest ładowany w kolekcji ModelValidationProviders.Providers. Masz jakieś pomysły?

Rozdzielczość powyżej wyjątku i następna

Aby rozwiązać problem w modelValidatorProviders musiałem ręcznie dodać obiekt, którego oczekiwał. Teraz moja metoda CreateKernel wygląda tak:

protected override IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());

    kernel.Bind<IRenderHelper>().To<RenderHelper>();
    kernel.Unbind<IDocumentViewerAdapter>();

    GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
    ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
    FilterProviders.Providers.Add(new FilterAttributeFilterProvider());
    return kernel;
}

Teraz działa i trafia do prawdziwych wnętrzności Ninject, ale wciąż ma problem, który nie ma sensu:

Exception Details: Ninject.ActivationException: Error activating IntPtr
No matching bindings are available, and the type is not self-bindable.
Activation path:
 3) Injection of dependency IntPtr into parameter method of constructor of type Func{IKernel}
 2) Injection of dependency Func{IKernel} into parameter lazyKernel of constructor of type HttpApplicationInitializationHttpModule
 1) Request for IHttpModule

Suggestions:
 1) Ensure that you have defined a binding for IntPtr.
 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.

questionAnswers(8)

yourAnswerToTheQuestion