39

更新 - 请查看我的答案以获取此问题的解决方案的链接和说明

在我们开始之前,我知道这是一个非常常见的问题,我已经使用 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)的其他项目的工作方式,据我所知,这是使一切正常工作所需要的。那么,为什么我突然得到没有为这个对象定义的无参数构造函数。例外?

更新

这是完整的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();
        }
    }
}

更新 - 请查看我的答案以获取此问题的解决方案的链接和说明

4

17 回答 17

48

我知道这是一个老问题,但似乎没有任何真正的答案,我已经解决了这个问题,所以这是我的解决方案:

创建自定义控制器工厂:

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

而已。

于 2012-12-25T04:36:13.580 回答
28

好吧,我没有确切的答案为什么会出现错误,但我知道是造成的,那就是 Visual Studio 2012。我在与 2012 年相同的机器上安装了 Visual Studio 2010,安装了 ASP.NET MVC 4对于 2010 年,我将 2012 年的项目重新创建为 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 的原因。

更新

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

基本上,这是使其工作的 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>

我猜这迫使框架意识到允许 Ninject 最终能够绑定的 IoC 容器。虽然,我不禁认为 Ninject NuGet 包应该在 Web.config 中寻找该绑定重定向的存在并自动添加它。它肯定会帮助解决这个问题上发生的很多问题。

PS 从我链接的那个帖子中投票赞成,因为它值得!

于 2012-09-07T21:19:40.987 回答
7

不要重新发明轮子,只需尝试 Install-Package Ninject.MVC3

于 2014-07-09T13:40:53.837 回答
3

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

问候,

于 2012-09-19T14:41:18.483 回答
2

整个事情太荒谬了,我切换到 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>
于 2014-06-14T06:19:41.857 回答
1

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

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

在 AppStart 事件开始时(或其他任何地方)

现在让我解释一下如果有人还没有得到窍门意味着什么。问题是我们的 http 应用程序类可以驻留在解决方案中的任何位置。不仅在 Web 应用程序中。这非常重要,因为 asp.net 编译例程与通常的库应用程序不同。它通过 BuildManager 帮助程序急切地加载所有引用的库,而通常 clr 不会从开始加载类型,除非它们被直接使用。

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

于 2013-07-28T15:06:25.697 回答
1

当使用带有 ASP.NET 4.0/4.5 的 Visual Studio 2012/2013 时,似乎会出现问题。的版本在文件System.Web.Mvc中设置为。那没起效。4.0.0.0Web.config

我的解决方案是

  1. 删除NinjectWebCommon.cs
  2. 将 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);
       }
    }
    
  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));
       }
    }
    

    之后,您的注射应该会起作用。

于 2014-01-09T02:55:47.887 回答
1

我遇到了这个问题,但仅限于 Web 服务调用。在这个答案上找到我的解决方案https://stackoverflow.com/a/12379938/129580下面是提供的示例代码

public class Service : WebService
{
  public IContextProvider ContextProvider {get;set;}

  public Service()
  {
    ContextProvider = DependencyResolver.Current.GetService<IContextProvider>();
  }
}

然后我最终变成了,希望这会有所帮助......

/// <summary>
/// Summary description for PartMarking
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class PartMarking : System.Web.Services.WebService
{
    private readonly IUnitOfWork _unitOfWork;

    public PartMarking()
    {
        _unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();
    }

    [WebMethod]
    public DataSet GetParentConfigurations(string engineModel, string componentCode)
    {
        var results = _unitOfWork.PartMarking.GetParentSicMarkings(engineModel, componentCode);
        return results;
    }
}
于 2018-08-08T13:34:06.073 回答
0

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

在此处输入图像描述

我不知道为什么,但是当我这样做时,我在 NinjectWebCommon 中的断点被击中。就像@Alex 所说,每次构建应用程序时,Visual Studio 2012 的亮度不足以执行 NinjectWebCommon 中的代码。也有可能是我不够聪明,无法理解它在引擎盖下是如何工作的。

我不喜欢我的解决方案,因为我更喜欢使用我的本地 IIS Web 服务器,但目前,我有一个应用程序要创建,并且花费了很多时间来处理这个 $%?!!/bug..feature..not sure .

于 2014-02-23T04:00:04.933 回答
0

正如所有以前的海报所说,这让我有些白发。就我而言,我已经“优化”了我的参考资料太多。Ninject.* 东西在那里,但已经被弄乱了。我删除了所有引用并手动清理了 packages.conf 并再次添加了包 - 胜利!

于 2013-07-09T10:14:55.683 回答
0

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

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

于 2014-05-16T03:48:13.647 回答
0

在我从 MVC 3 转移到 MVC 4 的最近一个项目中,我为此花了几个小时的时间。由于缺乏正确的答案,我认为这必须是我所做的事情,因为看起来 Ninject.MVC3 nuget包可以在 MVC 4 中正常工作——确实如此。

就我而言,我没有完全升级 MVC3 项目。遵循本指南后,我得到了按预期工作的东西。我的猜测是我错过了程序集绑定重定向。

因此,如果您将 MVC 3 项目升级到 MVC 4,使用 Ninject 并获得 no parameterless constructor defined 错误,希望这会有所帮助。

于 2013-06-13T13:56:47.833 回答
0

我尝试使用 MVC 5 设置 Ninject。最后我必须先使用带有控制器工厂的解决方案,然后再使用带有绑定重定向的解决方案。之后,一切都按预期工作。使用本地 IIS 服务器。

于 2014-05-30T22:45:02.687 回答
0

通过 Nuget 添加对 Ninject.Web.MVC 的引用为我解决了这个问题。

于 2014-04-28T21:06:08.240 回答
0

所有这一切的捷径:下载以下 Nuget 包之一:

  • Ninject.MVC3
  • Ninject.MVC5

这将处理您需要的绑定。

于 2016-05-25T21:57:41.283 回答
0

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

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

检查参考资料中 System.Web.MVC 的版本,以确定您当前使用的是哪个版本的 MVC。

于 2017-03-29T16:14:22.933 回答
0

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

于 2015-12-02T21:25:35.940 回答