2012-09-07 192 views
36

UPDATE定义无参数的构造函数 - 请看看我的答案为解决方案的这个问题ASP.NET MVC 4 + Ninject MVC 3 =此对象

一个链接,并解释我们开始之前,我知道这是一个非常普遍的问题,我一直在使用Ninject的许多卫星没有问题,但现在它出现了,我找不出一个修复。另外,不,Google和SO迄今为止的结果都没有帮助我。

因此,考虑下面的代码位上一个非常,非常,非常简单的原型ASP.NET MVC 4从Visual Studio 2012在Windows Server 2008 R2的项目运行:

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

,这是怎么了我的那个(在.NET 4中,但ASP.NET MVC 3)工作中使用Ninject和其他项目,据我所知,这是使一切工作所需的内容。那么,为什么我突然变得没有为这个对象定义无参数的构造函数。例外?

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

更新 - 请大家看我的回答对解决方案的链接,并解释了这个问题

+2

你在哪里创建你的DependecyResolver并覆盖默认值? – Josh

+0

我以为这就是'NinjectWebCommon.cs'文件正在做什么,如果没有,那么我想答案是“没有地方”。再一次,我的目标混乱,因为我的其他项目以这种方式工作,我已经检查了两倍和三倍,以确保我没有说谎... – Gup3rSuR4c

+0

Ninject.MVC包中有一个'NinjectMvcHttpApplicationPlugin',它负责'DependecyResolver'...所以它应该只是工作?你如何安装Ninject.MVC?用Nuget? – nemesv

回答

27

好,我没有一个确切的答案为什么的错误即将到来,但我知道谁是造成的,这是Visual Studio 2012.我在2012年的同一台机器上安装了Visual Studio 2010,2010年安装了ASP.NET MVC 4,并且我将2010年的项目重新创建为2010年逐字,字母的单词。最终的结果是,2010年调试项目时一切正常,Ninject按照它应该注入的依赖关系。

2012年调试它的项目时,它只是出现了No parameterless constructor defined for this object异常。在2012年.NET 4.0和.NET 4.5之间重新定位并不会做任何事情。从NuGet重新安装Ninject也无能为力。我甚至将2010和2012项目都配置为使用本地IIS服务器,以确保最终结果是一致的。

我打算假设Visual Studio 2012或Ninject存在一个错误。我的两个项目之间有唯一的区别是,他们是从运行的IDE和2012年项目是都崩溃了所以这就是为什么我指着手指在Visual Studio中的一个2012年

UPDATE

伙计们。伙计们!我再次遇到了这个问题,并在另一个SO问题中找到了解决方案:Ninject + MVC3 is not injecting into controller

基本上,这是网络上缺少的东西。配置这使它的工作:

<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中查找绑定重定向的存在并自动将其添加。这肯定会有助于在这个问题上发生大量的头发问题。

P.S.对那篇文章中的鼻涕进行投票,因为它值得!

+0

我看到了同样的问题。希望两者中的一个(VS 2012或Ninject)能解决这个问题。 –

+9

我的mvc4项目不会缺少这一行,但它仍然不起作用。 – liang

+0

正是我所需要的! – Rowan

3

从NuGet获得MVC3后,我得到了相同的错误消息。
我不知道你是否按照我的方式设置了项目设置,但是我的web.config是根据环境自动生成的。 NuGet的MVC将rows (<runtime>)添加到web.config,并且由于我的合并配置文件安装不正确,这些行被删除。

问候,

+1

我不得不将元素添加到我的网络配置中。以及确保具有targetFramework =“4.5”属性。这是我的运行时元素。 Michael

+0

喜欢@迈克尔,我需要以及增加运行时间为assemblybinding元素。Ninject.MVC4 – dbd

47

我知道这是一个老问题,但似乎并没有为任何真正的答案和我周围的问题,所以在这里工作是我的解决方案:

创建自定义控制器工厂:

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,那么在您创建内核并将它传递给新创建的内核的引用后,将该行添加到某处。

就是这样。

+1

真棒!伙计,你刚才救了我的一天。非常感谢!我花了时间试图解决这个问题,并解决了这个问题。顺便说一句,我真的很想知道为什么发生这种情况,你基本上用这个代码做了什么。 – rkrdo

+0

在我的例子中,我必须使用如下代码:“DynamicModuleUtility.RegisterModule (NinjectHttpModule));“在NinjectWebCommon的Start方法中,如果我用你的消息替换NinjectWebCommon,我不知道该移动这个代码的位置,如果我尝试在global.asax中移动它,我会收到一个错误,我在开始注册模块的过程中已经晚了,这就是为什么Ninject的大个子向我暗示保持使用NinjectWebCommon的解决方案。 – Samuel

+0

这会导致ASP MVC5,Ninject3.2,Ninject.MVC3的警告:“请勿将Ninject用作服务定位器”。该解决方案看起来像一个解决方法。 – SandRock

0

我最近在从MVC 3移植到MVC 4的项目上对我的头发进行了几个小时的测试。由于缺乏关于点的答案,我认为它必须是我所做的,因为看起来Ninject.MVC3 nuget包可以在MVC 4中正常工作 - 的确如此。

在我的情况下,我没有完全升级MVC3项目。在遵循this guide之后,我有事情按预期工作。我的猜测是我错过了一个程序集绑定重定向。

因此,如果您要将MVC 3项目升级到MVC 4,请使用Ninject并获取无参数构造函数定义的错误,希望这会有所帮助。

0

由于所有以前的海报已经表明这导致了一些灰色头发。在我的情况下,我对参考文献进行了“优化”。 Ninject。*的东西在那里,但已经变得糟糕了。我删除了所有的引用并清理了packages.conf manualli并再次添加了这些包 - 胜利!

1

这是一个肮脏的解决方案! 将这个

var type = typeof(Ninject.Web.Mvc.MvcModule); 

在AppStart的事件(或其他地方)的开头

现在让我来解释一下这是什么意思,如果有人没有得到欺骗呢。 事情是我们的http应用程序类可以驻留在解决方案的任何地方。不仅在Web应用程序中。这是非常重要的 ,因为asp.net编译例程不同于通常的库应用程序。它通过BuildManager helper热切加载所有引用的库,而通常clr不会从开始加载类型,除非直接使用它们。

现在让我们回到我们的情况:Ninject.Web.Mvc作为动态插件工作,在代码中不需要任何提及。因此,如果它在Class库中被引用导致Mvc.Dependancy初始化失败,则不会被加载。

1

当ASP.NET 4.0/4.5使用Visual Studio 2012/2013时,问题似乎就会发生。在Web.config文件中,System.Web.Mvc的版本被设置为4.0.0.0。它不起作用。

我的解决办法是

  1. 删除NinjectWebCommon.cs
  2. 复制代雷琼的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); 
        } 
    } 
    
  3. 变化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)); 
        } 
    } 
    

    之后,你的注射应该工作。

0

我有同样的问题,唯一对我有用的是将Web项目属性中的“本地IIS Web服务器”更改为“使用Visual Studio开发服务器”。

enter image description here

我不知道为什么,但我这样做的时候,我NinjectWebCommon断点hited。就像@Alex所说的那样,Visual Studio 2012中的东西在每次构建应用程序时都不够明亮,无法在NinjectWebCommon中执行代码。也有可能是我没有足够的明白了解它如何在引擎盖下工作。

我不喜欢我的解决方案,因为我宁愿使用我的本地IIS Web服务器,但目前,我有一个应用程序来创建和花费很多时间与这个$%?!!/bug..feature ..不确定。

+0

确保在你的'Web.config'中有''部分。我的项目使用本地IIS和该设置运行得很好。当然,从MVC 5.1版本开始,绑定重定向应该是'''。 – Gup3rSuR4c

0

这对我来说是通过添加一个通过Nuget到Ninject.Web.MVC的引用来解决的。

0

我尝试了所有这些解决方案,但都没有成功。

这就是我解决它的方法: 删除了所有我的临时asp.net文件。完成此操作后,我收到了新的配置错误。我修好了他们。最后一个,真正的错误出来了:新的Bootstrapper()试图加载一个ninject DLL的旧版本。 删除所有ninject软件包。 逐个安装ninject nuget软件包,确保安装正确的版本。

0

我试图用MVC 5设置Ninject。最后,我必须首先使用控制器工厂的解决方案,然后使用绑定重定向的解决方案。之后,所有的工作如预期。使用本地IIS服务器。

+1

我现在正在开发的项目是MVC 5(5.1.2),我不必使用控制器工厂。我只有绑定重定向,它都可以很好地工作。我也使用本地IIS服务器。我确实将Ninject代码从MVC项目中分离出来,然后分解到它自己的项目中。 – Gup3rSuR4c

1

整件事只是荒谬的,我转而使用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> 
7

不要重新发明轮子,只是尝试安装,包装Ninject.MVC3

+1

这是正确的答案。我做了安装包Ninject.MVC5,它工作。 – VivekDev

+0

钉住它。只需卸载Ninject MVC 3,再次安装,重建整个解决方案,运行并修复 –

0

我能够通过从我的控制器构造函数中删除#if #endif指令来解决MVC5 Web项目中的此问题。

0

快捷方式这一切:下载下面的NuGet Pacakges之一:

  • Ninject.MVC3
  • Ninject.MVC5

这将照顾绑定,你需要的。

0

我通过删除Ninject MVC5并从Nuget安装Ninject MVC3来修复我的问题。

MVC5 == Ninject.MVC5 
MVC4 == Ninject.MVC3 
MVC3 == Ninject.MVC3 

检查引用中的System.Web.MVC版本以确定您当前正在使用哪个版本的MVC。