MVC5,Web API 2和Ninject

我用Web API 2创build了一个新的MVC5项目,然后我从NuGet中添加了Ninject.MVC3包。

构造函数注入对于MVC5控制器来说工作正常,但是当试图将它与Web API控制器一起使用时,我得到一个错误。

尝试创buildtypes为“UserProfileController”的控制器时发生错误。 确保控制器有一个无参数的公共构造函数。

工作MVC5控制器的构造器:

public class HomeController : Controller { private IMailService _mail; private IRepository _repo; public HomeController(IMailService mail, IRepository repo) { _mail = mail; _repo = repo; } } 

非工作Web API控制器的构造函数:

 public class UserProfileController : ApiController { private IRepository _repo; public UserProfileController(IRepository repo) { _repo = repo; } } 

以下是完整的NinjectWebCommon.cs文件:

 [assembly: WebActivator.PreApplicationStartMethod(typeof(DatingSite.App_Start.NinjectWebCommon), "Start")] [assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(DatingSite.App_Start.NinjectWebCommon), "Stop")] namespace DatingSite.App_Start { using System; using System.Web; using Microsoft.Web.Infrastructure.DynamicModuleHelper; using Ninject; using Ninject.Web.Common; using DatingSite.Services; using DatingSite.Data; public static class NinjectWebCommon { private static readonly Bootstrapper bootstrapper = new Bootstrapper(); /// <summary> /// Starts the application /// </summary> public static void Start() { DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); bootstrapper.Initialize(CreateKernel); } /// <summary> /// Stops the application. /// </summary> public static void Stop() { bootstrapper.ShutDown(); } /// <summary> /// Creates the kernel that will manage your application. /// </summary> /// <returns>The created kernel.</returns> 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; } /// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { #if DEBUG kernel.Bind<IMailService>().To<MockMailService>().InRequestScope(); #else kernel.Bind<IMailService>().To<MailService>().InRequestScope(); #endif kernel.Bind<SiteContext>().To<SiteContext>().InRequestScope(); kernel.Bind<IRepository>().To<Repository>().InRequestScope(); } } } 

Ninject.Web.WebApi NuGet 包刚刚发布。 从现在开始,首选的解决scheme是使用该软件包。 我找不到任何相关的文件,但安装完包后,一切为我工作。

 Install-Package Ninject.Web.WebApi 

在安装之后,Ninject提供了正常的MVC和API控制器实例。

如果您已经安装了Ninject.Web.Common,请确保从NinjectWebCommon.cs保存您的绑定,并让Nuget在安装过程中重写NinjectWebCommon.cs,并在完成时放回您的绑定。

正如注释中所指出的,取决于您的执行上下文,您还需要以下软件包之一

  • Ninject.Web.WebApi.WebHost
  • Ninject.Web.WebApi.OwinHost
  • Ninject.Web.WebApi.Selfhost

最常见的情况是IISselectWebHost包。

如果您从头开始创buildIIS MVC5 Web应用程序,并且想要使用Ninject,请安装以下软件包:

  • Ninject – Ninject核心dll
  • Ninject.Web.Common – Ninject的通用Webfunction,例如。 InRequestScope()
  • Ninject.MVC5 – MVCdependency injection器例如。 为MVC提供控制器
  • Ninject.Web.Common.WebHost – 当IIS启动Web应用程序时,注册来自Ninject.MVC5的dependency injection器。 如果你不使用IIS,你将需要一个不同的包,上面的检查
  • Ninject.Web.WebApi WebApidependency injection器例如。 为WebApi提供控制器
  • Ninject.web.WebApi.WebHost – 当IIS启动Web应用程序时,注册Ninject.Web.WebApi中的dependency injection器。

您有这个问题,因为控制器和ApiController使用不同的依赖关系parsing器。 解决scheme非常简单。

首先创build依赖关系parsing器和依赖范围的新类。 你可以使用这个:

  public class NinjectResolver : NinjectScope, IDependencyResolver { private readonly IKernel _kernel; public NinjectResolver(IKernel kernel) : base(kernel) { _kernel = kernel; } public IDependencyScope BeginScope() { return new NinjectScope(_kernel.BeginBlock()); } } public class NinjectScope : IDependencyScope { protected IResolutionRoot resolutionRoot; public NinjectScope(IResolutionRoot kernel) { resolutionRoot = kernel; } public object GetService(Type serviceType) { IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true); return resolutionRoot.Resolve(request).SingleOrDefault(); } public IEnumerable<object> GetServices(Type serviceType) { IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true); return resolutionRoot.Resolve(request).ToList(); } public void Dispose() { IDisposable disposable = (IDisposable)resolutionRoot; if (disposable != null) disposable.Dispose(); resolutionRoot = null; } } 

之后,将下一行添加到NinjectWebCommon中的方法CreateKernel()

  GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel); 

我有同样的问题。 安装以下NuGet软件包之后:

  • Ninject
  • Ninject.web.WebApi
  • Ninject.web.WebApi.WebHost
  • Ninject.MVC3
  • Ninject.web.Common
  • Ninject.web.Common.WebHost

一切正常

我发现程序集Ninject.Web.WebApi.dll自动定义了自己的DependencyResolver并将其注册到类Ninject.Web.WebApi.WebApiModule中的内核中。

所以我只是添加到NinjectWebCommon.CreateKernel一行…

  GlobalConfiguration.Configuration.DependencyResolver = kernel.Get<System.Web.Http.Dependencies.IDependencyResolver>(); 

最后我的项目有以下依赖关系:

  • Ninject 3.2.0
  • Ninject.Web.Common 3.2.0
  • Ninject.Web.WebApi 3.2.4

只为其他人,可能有类似的设置,并像我一样通过谷歌来到这里。

我有多个应用程序使用一个WebApi项目。 如果我没有在RegisterServices方法中包含绑定,我会得到上述错误。 所以,在把头发拉出来之前,检查一下你是否有绑定的设置。 错误不会告诉你你有缺less绑定。 如果应用程序与WebApi在同一个项目中,它将会如何。

我最近不得不让Web Api 2工作,所以我可以回答这个问题的一部分。

这些是Web Api 2-

 Ninject Ninject.Web.Common Ninject.Web.Common.WebHost Ninject.Web.WebApi WebActivatorEx 

然后编辑NinjectWebCommon.CreateKernel(..)包括

 RegisterServices(kernel); // the next line is the important one GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); return kernel; 

我写了一个更详细的post – http://noDogmaBlog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/包括一个完整的解决scheme下载。;