ASP.NET MVC4中的Ninject

所以经过多次搞砸后,我终于将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 

我无法追踪甚至开始了解它的来源。

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

  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框架连接到运行在.NET 4.5上的最新MVC4 RC,并且现在刚刚达到我的容忍水平,因为根本没有工作的东西。

编辑#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. 

好久打了我的头靠在墙上太久了,我弄明白发生了什么事。 在.NET 4.5上运行的MVC4的默认项目类型引用了System.Web.Http的原始RC版本而不是更新版本。

命名空间丢失,对象不存在,生活不好。

解决步骤:

  1. 删除MVC4项目中对System.Web.Http的引用
  2. 添加引用 – > System.Web.Http
  3. 删除您放入的所有工作,以使旧的垃圾版本的System.Web.Http工作
  4. 在Ninject中重新应用标准流程进行连线。

    但是,错误:

    exception详细信息:Ninject.ActivationException:激活IntPtr时出错没有可用的匹配绑定,并且该类型不可自我绑定。 激活路径:3)将依赖IntPtr注入到Func {IKernel}类型的构造函数的参数方法中2)将依赖项Func {IKernel}注入到HttpApplicationInitializationHttpModule类型的构造函数的参数lazyKernel中1)请求IHttpModule

    建议:1)确保已为IntPtr定义了绑定。 2)如果在模块中定义了绑定,请确保已将模块加载到内核中。 3)确保您没有意外创建多个内核。 4)如果使用构造函数参数,请确保参数名称与构造函数参数名称匹配。 5)如果使用自动模块加载,请确保搜索路径和filter正确无误。

更新这是通过将MVC从MVC4 Beta更新为MVC4 RC来解决的。

查看Pro ASP.NET MVC 3书 。 我昨晚刚将这段代码从MVC3移植到MVC4并正常工作。 确切地说是第322页。

我没看到的是您将接口映射到具体项目的位置。

 Bind().To(); 

添加另一个构造函数并添加调用映射的方法;

 public NinjectDependencyResolver() { _kernal = new StandardKernel(); RegisterServices(_kernel); } public static void RegisterServices(IKernel kernel) { kernel.Bind().To(); } 

这是解析器可能/应该是什么样子;

  public class NinjectDependencyResolver : IDependencyResolver { private IKernal _kernel; public NinjectDependencyResolver(){ _kernal = StandardKernal(); AddBindings(); } public NinjectDependencyResolver(IKernel kernel) { _kernel = kernel; } public object GetService(Type serviceType) { return _kernel.TryGet(serviceType); } public IEnumerable GetServices(Type serviceType) { return _kernal.GetAll(serviceType); } public IBindingToSyntax Bind() { return _kernal.Bind(); } public static void RegisterServices(IKernel kernel){ //Add your bindings here. //This is static as you can use it for WebApi by passing it the IKernel } } 

Global.Asx –

的Application_Start()

方法

 DependencyResolver.SetResolver(new NinjectDependencyResolver()); 

而已。


更新于2012年11月14日

另外,如果您正在使用MVC WebAPI,则需要使用nuget中的WebApiContrib.IoC.Ninject。 另外,请查看样本asp.net.com中的“联系人管理器”。 这有助于清理Ninject的实现

只需从项目中删除NinjectWebCommon.cs文件(它位于App_Start文件夹中)。 一切都应该有效。

资料来源: http : //mlindev.blogspot.com.au/2012/09/how-to-implement-dependency-injection.html

当您从NuGet包安装最新的Ninject.MVC3时,我们在NinjectWebCommon.cs文件的顶部找到以下代码:

 [assembly: WebActivator.PreApplicationStartMethod(typeof(MvcApplication1.App_Start.NinjectWebCommon), "Start")] [assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MvcApplication1.App_Start.NinjectWebCommon), "Stop")] 

在这种情况下,我们不需要在global.asax中明确注册ninject

我在这里找到了使用Ninject和MVC 4的好内容

我倾向于将我的Ninject引导保持在一个单独的项目中。 为了使用IBindingInSyntax.InRequestScope()扩展方法,我通过Nuget添加了Ninject.Web.Common库。 唉,这个库包含了app_start引导程序,通过WebActivator产生了重复的NinjectWebCommon类和附件(所述项目中有1个,MVC项目中有1个)。

我从我的bootstrap项目中删除了重复的App_Start文件夹,这解决了它。

我遇到过同样的问题,不太确定在下面的修改后修复了什么

将Ninject.MVC4添加到项目中

删除了NinjectWebCommon.cs(生成的文件,因为整合已存在于global.ascx.cs文件中)

我正在使用DD4T,遇到同样的错误。

确认所有包都是由nuget包管理器安装后,我发现有些DLL /引用丢失了(newtonsoft等):

然后,重新安装Newtonsoft.Json(在Nuget包管理器中重新安装包使用以下命令:Update-Package -reinstall Newtonsoft.Json),并从Netidn Deployer bin中放入netrtsn.dll,我收到此错误 – “Sequence不包含“与此问题中给出的堆栈跟踪完全相同的元素”。

感谢Naga,为了提供这个解决方案,删除了NinjectWebCommon.cs(生成的文件,因为整合已经存在于global.ascx.cs文件中),并且wohooooo !!!! 所有错误都解决了,Tridion + MVC4 = DD4T现在正常运行。

当我使用nuget在我的实际MVC网站项目引用的项目中安装Ninject.MVC4时,我也遇到了这个问题。

问题是自动安装在引用项目的App_Start目录中的NinjectWebCommon.cs文件与我的网站项目中安装的(实际的,有用的)冲突。 从引用的项目中删除NinjectWebCommon.cs文件可以解决该错误。