Внедрение в ASP.NET MVC4

Итак, после долгих раздумий я, наконец, подключил Ninject и скомпилировал его в своем приложении MVC4. Проблема, с которой я столкнулся, заключается в том, что интерфейс IDependencyScope больше не существует, насколько я могу судить, и с пространством имен System.Web.Http.Dependencies было покончено.

Итак, моя проблема сейчас в том, что у меня все подключено, и после запуска приложения я получаю:

    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.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

Который я не смог отследить или даже начать понимать, откуда он исходит.

Мои стандартные методы Ninject внутри Global.asax.cs выглядят следующим образом:

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

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

И мой пользовательский преобразователь:

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 GetServices(Type serviceType)
     {
         try
         {
             return _kernel.GetAll(serviceType);
         }
         catch (Exception)
         {
             return new List();
         }
     }

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

Любое понимание здесь будет с благодарностью. Я уже потратил слишком много времени, пытаясь подключить любую инфраструктуру DI к последней версии MVC4 RC, работающей на.NET 4.5, и только что достиг своего уровня терпимости к вещам, которые просто не работают вообще..

Редактировать #1 Небольшие дальнейшие исследования в github ExtensionsForIEnumerableOfT.cs не очень помогают :

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

. И, возможно, если бы я написал это сам, я бы начал это понимать, но Bootstrapper.cs тоже не слишком помогает.

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

Надеемся, что эти детали облегчат работу любому из вас, у кого может быть больше опыта работы с Ninject.

Редактировать #2 Возникла ошибка конкретно в NinjectMvcHttpApplicationPlugin.cs:

Нарушение линии:

ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType().Single());

Который живет в следующем методе:

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

Коллекция ModelValidatorProviders содержит 2 элемента :{System.Web.Mvc.DataErrorInfoModelValidatorProvider} {System.Web.Mvc.ClientDataTypeModelValidatorProvider}

И он пытается удалить один экземпляр:

System.Web.Mvc.DataAnnotationsModelValidatorProvider

Который, по-видимому, не загружен в коллекцию ModelValidationProviders.Providers. Любые идеи отсюда?

Разрешение выше исключения и переход к следующему

Чтобы решить проблему в ModelValidatorProviders, мне пришлось вручную добавить ожидаемый объект. Итак, теперь мой метод CreateKernel выглядит как:

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

    kernel.Bind().To();
    kernel.Unbind();

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

Теперь он запускается и попадает в настоящие кишки Ninject, но все еще имеет проблему, которая снова не имеет смысла:

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.

20
задан VulgarBinary 13 July 2012 в 13:33
поделиться