ASP.NET MVC 4 + Ninject MVC 3 =没有为此对象定义的无参数构造函数

Gup*_*R4c 39 c# asp.net-mvc ninject asp.net-mvc-4 visual-studio-2012

更新 - 请查看我的答案,找到解决此问题的链接和说明

在我们开始之前,我知道这是一个非常常见的问题,我一直在使用Ninject进行许多卫星没有问题,但是现在它出现了,我无法找到解决办法.此外,不,迄今为止谷歌和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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是NinjectWebCommon.cs RegisterServices方法:

kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor(
    c =>
        new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "?", "?", "?", "?"))).InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

现在,这就是我使用Ninject的其他项目(但是.NET 4上的ASP.NET MVC 3)的工作原理,据我所知,这是使一切正常运行所需要的.那么,为什么我突然得到为此对象定义的无参数构造函数.异常?

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新 - 请查看我的答案,找到解决此问题的链接和说明

Jer*_*nes 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,如果您使用的是NinjectHttpApplication,请将以下行添加到OnApplicationStarted:

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel));
Run Code Online (Sandbox Code Playgroud)

如果您没有使用NinjectHttpApplication,那么在创建内核后将该行添加到某处,并将其引用给新创建的内核.

而已.


Gup*_*R4c 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.

UPDATE

伙计们.伙计们!我遇到了这个问题,并在另一个SO问题中找到了解决方案: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>
Run Code Online (Sandbox Code Playgroud)

我猜这迫使框架了解IoC容器,它允许Ninject最终能够绑定.虽然,我不禁想到Ninject NuGet包应该在Web.config中寻找绑定重定向的存在并自动神奇地添加它.这肯定会有助于在这个问题上发生很多事情.

PS Up-vote the snot from the post我链接,因为它应该得到它!

  • 我的mvc4项目没有错过这一行,但它仍然不起作用. (10认同)

Jua*_*njo 7

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