ASP.NET MVC 4 + Ninject MVC 3 =没有为此对象定义的无参数构造函数
更新 – 请看我的答案,以解决这个问题的链接和解释
在我们开始之前,我知道这是一个非常普遍的问题,我已经使用Ninject的许多卫星没有问题,但现在它出现了,我不能找出一个修复。 另外,不,Google和SO迄今为止的结果都没有帮助我。
所以,考虑下面的代码在Windows Server 2008 R2上从Visual Studio 2012的一个非常非常非常简单的原型ASP.NET MVC 4项目上运行:
public class DefaultController : Controller { private IGroupPrincipalRepository GroupPrincipalRepository { get; set; } [Inject] public DefaultController( IGroupPrincipalRepository groupPrincipalRepository) { this.GroupPrincipalRepository = groupPrincipalRepository; } }
这里是NinjectWebCommon.cs RegisterServices
方法:
kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor( c => new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "?", "?", "?", "?"))).InSingletonScope();
现在,这就是我使用Ninject的其他项目(但.NET 4上的ASP.NET MVC 3)的工作方式,据我所知,这是使一切正常工作所需的。 那么,为什么我突然变得没有为这个对象定义无参数的构造函数。 exception?
UPDATE
以下是完整的NinjectWebCommon.cs
文件:
[assembly: WebActivator.PreApplicationStartMethod(typeof(App_Start.NinjectWebCommon), "Start")] [assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(App_Start.NinjectWebCommon), "Stop")] namespace App_Start { using System; using System.DirectoryServices.AccountManagement; using System.Repositories.ActiveDirectory; using System.Web; using Microsoft.Web.Infrastructure.DynamicModuleHelper; using Ninject; using Ninject.Web.Common; public static class NinjectWebCommon { private static readonly Bootstrapper bootstrapper = new Bootstrapper(); public static void Start() { DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); bootstrapper.Initialize(CreateKernel); } public static void Stop() { bootstrapper.ShutDown(); } private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); RegisterServices(kernel); return kernel; } private static void RegisterServices( IKernel kernel) { kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor( c => new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "", "", "", ""))).InSingletonScope(); } } }
更新 – 请看我的答案,以解决这个问题的链接和解释
我知道这是一个古老的问题,但似乎没有任何真正的答案,我已经解决了这个问题,所以这里是我的解决scheme:
创build一个定制控制器工厂:
public class NinjectControllerFactory : DefaultControllerFactory { private IKernel ninjectKernel; public NinjectControllerFactory(IKernel kernel) { ninjectKernel = kernel; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType); } }
然后,如果您正在使用NinjectHttpApplication,请将以下行添加到OnApplicationStarted:
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel));
如果您不使用NinjectHttpApplication,那么在创build内核之后将该行添加到某处,并将其传递给新创build的内核。
而已。
那么,我没有一个确切的答案, 为什么错误即将到来,但我知道是谁造成它,这是Visual Studio 2012年。我安装Visual Studio 2010在同一台计算机上2012年,安装ASP.NET MVC 4对于2010年,我重新将2010年的项目再造成2010年的一个字,信件的信。 最终的结果是,2010年debugging项目时,一切正常,Ninject应该注入依赖关系。
当2012debugging它的项目时,它只是No parameterless constructor defined for this object
exception提供了No parameterless constructor defined for this object
。 在2012年.NET 4.0和.NET 4.5之间重新定位并不会做任何事情。 从NuGet重新安装Ninject也不会做任何事情。 我甚至configuration了2010和2012两个项目,使用本地IIS服务器是绝对确定的,最终结果是一样的。
我将假设Visual Studio 2012或Ninject存在一个错误。 我在这两个项目之间唯一的区别是他们运行哪个IDE,2012年的项目是崩溃的,所以这就是为什么我要指责Visual Studio 2012。
UPDATE
伙计们。 伙计们! 我再次遇到这个问题,并在另一个SO问题中find解决scheme: Ninject + MVC3不注入到控制器 。
基本上,这是什么从Web.config使它的工作:
<dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly>
我猜这迫使框架了解IoC容器,它允许Ninject终于能够绑定。 虽然,我忍不住想Ninject NuGet包应该在Web.config中查找绑定redirect的存在,并自动将其添加。 这肯定会有助于在这个问题上发生大量的头发问题。
聚苯乙烯投票的鼻涕出我的链接,因为它值得!
不要重新发明轮子,只要尝试安装包Ninject.MVC3
从NuGet获得MVC3后,我得到了同样的错误信息。
我不知道是否你的项目设置与我一样,但是我的web.config
是根据环境自动生成的。 NuGet的MVC正在向web.config
添加rows (<runtime>)
,由于我的合并configuration文件没有正确设置,所以这些行被移除了。
问候,
金
这是个肮脏的解决scheme! 把这个
var type = typeof(Ninject.Web.Mvc.MvcModule);
在AppStart事件的开始(或其他地方)
现在让我解释一下,如果有人还没有弄明白这是什么意思。 事情是我们的http应用程序类可以驻留在解决scheme的任何地方。 不仅在networking应用程序。 这是非常重要的,因为asp.net编译例程不同于通常的库应用程序。 它通过BuildManager助手热切地加载所有引用的库,而通常clr不会从开始加载types,除非直接使用它们。
现在让我们回到我们的情况:Ninject.Web.Mvc作为dynamic插件,在代码中不需要任何提及。 因此,如果在类库中引用了它,则会导致Mvc.Dependancy初始化中断。
当ASP.NET 4.0 / 4.5使用Visual Studio 2012/2013时,问题似乎就会发生。 System.Web.Mvc
的版本在Web.config
文件中设置为4.0.0.0
。 它不起作用。
我的解决办法是
- 删除
NinjectWebCommon.cs
-
将Dere Jone的
NinjectControllerFactory
类复制到项目中:public class NinjectControllerFactory : DefaultControllerFactory { private IKernel ninjectKernel; public NinjectControllerFactory(IKernel kernel) { ninjectKernel = kernel; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType); } }
-
将
Global.asax
的内容更改为:public class MvcApplication : NinjectHttpApplication { protected override IKernel CreateKernel() { IKernel kernel = new StandardKernel(); // kernel.Load(Assembly.GetExecutingAssembly()); // kernel.Bind<ISomeClass>().To<SomeClass>(); return kernel; } protected override void OnApplicationStarted() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel)); } }
之后,你的注射应该工作。
整个事情只是荒谬的,我转向Autofac,厌倦了从来没有能够成功地添加Ninject项目。 Web API,MVC4,MVC5都有问题。
对于MVC5人,使用Ninject MVC3,将以下内容添加到web.config应用程序级别:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/> <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0"/> </dependentAssembly> </assemblyBinding> </runtime>
最近我从MVC 3移植到MVC 4的项目上,我在这个问题上拖了好几个小时。由于缺乏点的答案,我认为它必须是我所做的,因为看起来Ninject.MVC3 nuget包与MVC 4将正常工作 – 的确如此。
在我的情况下,我没有完全升级MVC3项目。 遵循本指南后,我得到了预期的工作。 我的猜测是,我错过了一个程序集绑定redirect。
所以,如果你是MVC 3项目升级到MVC 4,使用Ninject和获取无参数构造函数定义错误,希望这会有所帮助。
正如以前的所有海报都说过的,这使我有些灰白的头发。 在我的情况下,我已经“优化”了我的参考。 Ninject。*东西在那里,但已经被弄坏了。 我删除了所有的引用和清理packages.conf manualli并再次添加包 – 胜利!
我有同样的问题,唯一对我有用的是将Web项目属性中的“本地IIS Web服务器”更改为“使用Visual Studio开发服务器”。
我不知道为什么,但是当我这样做的时候,我在NinjectWebCommon的中断点被激活了。 就像@Alex所说的那样,Visual Studio 2012中的东西在每次构build应用程序时都不够明亮,无法在NinjectWebCommon中执行代码。 这也可能是我没有足够的光明,了解它是如何工作的。
我不喜欢我的解决scheme,因为我宁愿使用我的本地IIS Web服务器,但目前,我有一个应用程序来创build,并花了很多时间与这个$%?!! / bug ..feature ..不确定。
这是通过添加到Ninject.Web.MVC通过Nuget的引用解决了我。
我尝试了所有这些解决scheme,但都没有成功。
这是我解决它的方法:删除所有我的临时asp.net文件。 完成这个之后,我得到了新的configuration错误。 我修好了他们 最后,真正的错误出来了:新的Bootstrapper()试图加载一个ninject DLL的旧版本。 删除所有ninject包。 逐个安装ninject nuget软件包,确保安装正确的版本。
我尝试使用MVC 5来设置Ninject。最后,我必须首先使用控制器工厂的解决scheme,然后使用绑定redirect的解决scheme。 之后,所有的预期工作。 使用本地IIS服务器。
我能够通过从我的控制器构造函数中删除#if #endif指令来解决MVC5 Web项目中的这个问题。
所有这些快捷方式:下载以下Nuget Pacakges之一:
-
Ninject.MVC3
-
Ninject.MVC5
这将照顾你需要的绑定。
我通过删除Ninject MVC5并从Nuget安装Ninject MVC3来修复我的问题。
MVC5 == Ninject.MVC5 MVC4 == Ninject.MVC3 MVC3 == Ninject.MVC3
检查引用中的System.Web.MVC的版本以确定您当前正在使用哪个版本的MVC。