Ninject在ASP.NET MVC4 [英] Ninject in ASP.NET MVC4

查看:748
本文介绍了Ninject在ASP.NET MVC4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

于是经过一番胡闹我终于Ninject在有线和我MVC4应用程序编译。我快到的问题是IDependencyScope接口不再从我可以告诉的存在和System.Web.Http.Dependencies命名空间与做了。

所以,我现在的问题是我的一切和运行时我得到了应用程序的接线方式:

 序列不包含任何元素    [出现InvalidOperationException:序列不包含任何元素]
   System.Linq.Enumerable.Single(IEnumerable`1源)379
   Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin.Start()在C:\\项目\\ Ninject \\ ninject.web.mvc \\ MVC3的\\ src \\ Ninject.Web.Mvc \\ NinjectMvcHttpApplicationPlugin.cs:53
   Ninject.Web.Common.Bootstrapper<初始化>在C b__0(INinjectHttpApplicationPlugin C):\\项目\\ Ninject \\ Ninject.Web.Common的\\ src \\ Ninject.Web.Common \\ Bootstrapper.cs:52
   Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable`1系列,Action`1动作)在C:\\项目\\ Ninject \\ ninject的\\ src \\ Ninject \\基础设施\\语言\\ ExtensionsForIEnumerableOfT.cs:31
   Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback)在C:\\项目\\ Ninject \\ Ninject.Web.Common的\\ src \\ Ninject.Web.Common \\ Bootstrapper.cs:53
   Ninject.Web.Common.NinjectHttpApplication.Application_Start()在C:\\项目\\ Ninject \\ Ninject.Web.Common的\\ src \\ Ninject.Web.Common \\ NinjectHttpApplication.cs:81

对此我一直无法追查,甚至开始捉摸它是从哪里过来。

我的Global.asax.cs中内部标准Ninject方法如下所示:

 保护覆盖的iKernel CreateKernel()
        {
            VAR内核=新StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            kernel.Bind&所述; IRenderHelper方式>()到< RenderHelper>();            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(新NinjectDependencyResolver(内核));
            返回内核;
        }        保护覆盖无效OnApplicationStarted()
        {
            base.OnApplicationStarted();
            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            的RegisterRoutes(RouteTable.Routes);
            BundleTable.Bundles.RegisterTemplateBundles();
        }

和我的自定义解析:

 公共类NinjectDependencyResolver:的IDependencyResolver
{
    私人只读的iKernel _KERNEL;    公共NinjectDependencyResolver(内核的iKernel)
    {
        _KERNEL =内核;
    }    公共对象GetService的(类型的serviceType)
     {
         返回_kernel.TryGet(的serviceType);
     }     公共IEnumerable的<对象> GetServices(类型的serviceType)
     {
         尝试
         {
             返回_kernel.GetAll(的serviceType);
         }
         赶上(例外)
         {
             返回新的List<对象>();
         }
     }     公共无效的Dispose()
     {
         //当BeginScope返回'这个',Dispose方法必须是一个空操作。
     }
}

下面的任何有识之士将不胜AP preciated。我花了太多时间已经试图让连线到在.NET 4.5的最新MVC4 RC运行任何DI框架,现在刚刚达到我的事情就不是在所有的工作承受能力。

编辑#1
再往研究GitHub上ExtensionsForIEnumerableOfT.cs四处没有太多帮助:

<一个href=\"https://github.com/ninject/ninject/blob/master/src/Ninject/Infrastructure/Language/ExtensionsForIEnumerableOfT.cs\">https://github.com/ninject/ninject/blob/master/src/Ninject/Infrastructure/Language/ExtensionsForIEnumerableOfT.cs

和可能,如果我自己写的我也开始明白这一点,但Bootstrapper.cs没有帮助太多无论是。

<一个href=\"https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs\">https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs

希望能这些细节将使它更容易为任何你谁可能与Ninject更多的经验。

编辑#2 遇到的错误特别是在NinjectMvcHttpApplicationPlugin.cs:

问题的行是:

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

哪住在下面的方法:

 公共无效启动()
{
    ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
    DependencyResolver.SetResolver(this.CreateDependencyResolver());
    RemoveDefaultAttributeFilterProvider();
}

该ModelValidatorProviders集合包含两个元素:
{} System.Web.Mvc.DataErrorInfoModelValidatorProvider
{} System.Web.Mvc.ClientDataTypeModelValidatorProvider

和它试图删除的一个实例:

System.Web.Mvc.DataAnnotationsModelValidatorProvider

这显然在ModelValidationProviders.Providers集合不会装起来。从这里任何想法?

解决上述异常,并到下一步

要解决该问题在ModelValidatorProviders我不得不手动添加一个对象时,它期待。所以,现在我CreateKernel方法如下:

 保护覆盖的iKernel CreateKernel()
{
    VAR内核=新StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());    kernel.Bind&所述; IRenderHelper方式&gt;()到&lt; RenderHelper&GT;();
    kernel.Unbind&LT; IDocumentViewerAdapter&GT;();    GlobalConfiguration.Configuration.ServiceResolver.SetResolver(新NinjectDependencyResolver(内核));
    ModelValidatorProviders.Providers.Add(新DataAnnotationsModelValidatorProvider());
    FilterProviders.Providers.Add(新FilterAttributeFilterProvider());
    返回内核;
}

现在它运行并进入Ninject实际的胆量,但仍然有一个问题,一个是没有意义的再一次:

 异常详细信息:Ninject.Activati​​onException:错误激活的IntPtr
没有匹配的绑定是可用的,并且类型不是自我绑定。
激活路径:
 3)依赖的IntPtr注射入式Func键{}的iKernel的构造函数的参数法
 2)依赖Func键{}的iKernel注射入式的构造函数参数lazyKernel HttpApplicationInitializationHttpModule
 1)请给IHttpModule的建议:
 1)确保您已经定义了IntPtr的绑定。
 2)如果一个模块中定义的结合,确保模块已被加载到内核中。
 3)确保你不小心创建了多个内核。
 4)如果你使用的是构造函数的参数,确保参数名称参数构造函数名称匹配。
 5)如果你使用的是自动加载模块,保证了搜索路径和过滤器是正确的。


解决方案

好打我的头撞在墙上的时间​​太长了我想通了是怎么回事了。对.NET 4.5运行MVC4默认的项目类型有原来的RC版System.Web.Http代替的更新版本的引用。

命名空间不翼而飞,对象是不存在的,生活并不好。

为解决步骤:


  1. 在MVC4项目中删除您参考System.Web.Http

  2. 添加引用 - > System.Web.Http

  3. 删除你把获得System.Web.Http的旧垃圾版本的所有工作变通工作

  4. 重新应用Ninject标准过程中丝。

    但是,错误:

    异常详细信息:Ninject.Activati​​onException:错误激活的IntPtr
    没有匹配的绑定是可用的,并且类型不是自我绑定。
    激活路径:
     3)依赖的IntPtr注射入式Func键{}的iKernel的构造函数的参数法
     2)依赖Func键{}的iKernel注射入式的构造函数参数lazyKernel HttpApplicationInitializationHttpModule
     1)请给IHttpModule的

    建议:
     1)确保您已经定义了IntPtr的绑定。
     2)如果一个模块中定义的结合,确保模块已被加载到内核中。
     3)确保你不小心创建了多个内核。
     4)如果你使用的是构造函数的参数,确保参数名称参数构造函数名称匹配。
     5)如果你使用的是自动加载模块,保证了搜索路径和过滤器是正确的。


更新这是由MVC4 Beta版更新到MVC RC MVC4解决。

So after much screwing around I finally got Ninject wired in and compiling in my MVC4 application. The problem I was running into is the IDependencyScope interface no longer exists from what I can tell and the System.Web.Http.Dependencies namespace was done away with.

So, my problem now is I have everything wired in and upon running the application I get:

    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

Which I haven't been able to track down or even begin to fathom where it is coming from.

My standard Ninject methods inside the Global.asax.cs look as follows:

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

And my custom resolver:

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

Any insight here would be greatly appreciated. I've spent far too much time already trying to get any DI framework wired into the latest MVC4 RC running on .NET 4.5 and have now just reached my tolerance level for things just not working at all..

Edit #1 A little further research digging around in github the ExtensionsForIEnumerableOfT.cs doesn't help much:

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

And possibly if I had wrote it myself I would begin to understand this but Bootstrapper.cs doesn't help too much either.

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

Hoping these details will make it easier for any of you who might have more experience with Ninject.

Edit #2 The error encountered is specifically in NinjectMvcHttpApplicationPlugin.cs:

The offending line is:

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

Which lives in the following method:

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

The ModelValidatorProviders collection contains 2 elements: {System.Web.Mvc.DataErrorInfoModelValidatorProvider} {System.Web.Mvc.ClientDataTypeModelValidatorProvider}

And it's trying to remove a single instance of:

System.Web.Mvc.DataAnnotationsModelValidatorProvider

Which apparently isn't loaded up in the ModelValidationProviders.Providers collection. Any ideas from here?

Resolution to Above Exception And Onto The Next

To resolve the issue in the ModelValidatorProviders I had to manually add an object it was expecting. So now my CreateKernel method looks like:

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

Now it runs and gets into the actual guts of Ninject but still has an issue, one that makes no sense yet again:

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.

解决方案

Ok after beating my head against the wall for far too long I figured out what was going on. The default project type for MVC4 running on .NET 4.5 had a reference to the original RC version of System.Web.Http instead of the updated version.

Namespaces were missing, objects didn't exist, life was not good.

Steps for resolution:

  1. Remove your reference to System.Web.Http in your MVC4 project
  2. Add Reference -> System.Web.Http
  3. Delete all work arounds you put in to get the old garbage version of System.Web.Http to work
  4. Reapply standard process to wire in Ninject.

    HOWEVER, the error of:

    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.

Update This was solved by updating MVC from MVC4 Beta to MVC4 RC.

这篇关于Ninject在ASP.NET MVC4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆