MVC5, Web API 2 y Ninject

Creé un nuevo proyecto MVC5 con Web API 2, luego agregué el paquete Ninject.MVC3 de NuGet.

La inyección de Constructor funciona bien para los controladores MVC5, pero estoy recibiendo un error al intentar usarlo con los Controladores Web API.

Se produjo un error al intentar crear un controlador de tipo ‘UserProfileController’. Asegúrese de que el controlador tenga un constructor público sin parámetros.

Constructor para el funcionamiento del controlador MVC5:

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

Constructor para el controlador Web API que no funciona:

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

A continuación se muestra el archivo completo 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(); ///  /// Starts the application ///  public static void Start() { DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); bootstrapper.Initialize(CreateKernel); } ///  /// Stops the application. ///  public static void Stop() { bootstrapper.ShutDown(); } ///  /// Creates the kernel that will manage your application. ///  /// The created kernel. private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind().To(); RegisterServices(kernel); return kernel; } ///  /// Load your modules or register your services here! ///  /// The kernel. private static void RegisterServices(IKernel kernel) { #if DEBUG kernel.Bind().To().InRequestScope(); #else kernel.Bind().To().InRequestScope(); #endif kernel.Bind().To().InRequestScope(); kernel.Bind().To().InRequestScope(); } } } 

El paquete Ninject.Web.WebApi NuGet acaba de ser lanzado. A partir de ahora, la solución preferida es usar ese paquete. No pude encontrar ninguna documentación relacionada, pero después de instalar el paquete todo funcionó para mí.

 Install-Package Ninject.Web.WebApi 

Después de la instalación, Ninject proporciona las instancias normales de controlador MVC y MVC.

Si tienes Ninject.Web.Common ya instalado, asegúrate de guardar tus enlaces de NinjectWebCommon.cs y deja que Nuget vuelva a escribir NinjectWebCommon.cs durante la instalación y vuelve a poner tus enlaces cuando termines.

Como se señala en los comentarios según el contexto de ejecución, también necesitará uno de los siguientes paquetes:

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

El escenario más común es IIS para que elija el paquete WebHost.

En el caso de que inicie una aplicación web IIS MVC5 desde cero y desee usar Ninject, instale los siguientes paquetes:

  • Ninject – Ninject core dll
  • Ninject.Web.Common : funcionalidad web común para Ninject, por ej. InRequestScope ()
  • Ninject.MVC5 – Inyectores de dependencia MVC, por ejemplo. para proporcionar controladores para MVC
  • Ninject.Web.Common.WebHost : registra los inyectores de dependencia de Ninject.MVC5 cuando IIS inicia la aplicación web. Si no está utilizando IIS necesitará un paquete diferente, verifique arriba
  • Inyectores de dependencia Ninject.Web.WebApi WebApi, p. Ej. proporcionar controladores para WebApi
  • Ninject.web.WebApi.WebHost : registra los inyectores de dependencia de Ninject.Web.WebApi cuando IIS inicia la aplicación web.

Tiene este problema porque Controller y ApiController usan diferentes Resolvadores de Dependencia. La solución es muy simple.

Al principio cree nuevas clases de Dependency Resolver y Dependency Scope. Puedes usar esto:

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

Después de eso, agrega la siguiente línea al método CreateKernel () en NinjectWebCommon

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

Yo tuve el mismo problema. Después de la instalación de los siguientes paquetes NuGet:

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

todo funciona bien

Se encontró que el ensamblado Ninject.Web.WebApi.dll define el propio DependencyResolver y lo registra con kernel en la clase Ninject.Web.WebApi.WebApiModule automáticamente.

Así que simplemente agrego a NinjectWebCommon.CreateKernel una línea …

 GlobalConfiguration.Configuration.DependencyResolver = kernel.Get(); 

Finalmente mi proyecto tiene las siguientes dependencias:

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

Solo para otros, que podrían tener una configuración similar a la mía, y llegaron aquí a través de google como yo.

Tenía varias aplicaciones usando un proyecto de WebApi. Me gustaría obtener el error anterior si no hubiera incluido el enlace en el método RegisterServices. Entonces, antes de quitarte el pelo, solo asegúrate de que tienes la configuración de encuadernación. El error no le dice que le faltan enlaces. Lo que sucedería si la aplicación está en el mismo proyecto que WebApi.

Recientemente tuve que trabajar con Web Api 2 para poder responder esa parte de la pregunta.

Estos son los paquetes nuget necesarios para Web Api 2-

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

Luego edite NinjectWebCommon.CreateKernel(..) incluyendo

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

He escrito una publicación más detallada sobre esto: http://NoDogmaBlog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/, incluido un completo solución para descargar.

Tuve este problema en una solución donde el proyecto en el que estaba usando Ninject no usaba Web API (tengo 6 proyectos hasta ahora en mi solución). Seguí obteniendo el temido “constructor sin parámetros requerido”, lo que obviamente significaba que cuando añadí la inyección de Ninject no se estaba creando una instancia ya que estaba cayendo en el constructor vacío. Intenté varias soluciones, pero al final revisé mis paquetes de Ninject y vi que el paquete Ninject.Web.Webapi estaba instalado. Desinstalé esto e hice una limpieza y reconstrucción. Esto resolvió el problema. Mi otro proyecto de nivel inferior estaba haciendo referencia al paquete Ninject.Web.Api y estúpidamente lo había instalado en mi proyecto web front-end.

Espero que esto pueda ayudar a otras personas que han probado todas las soluciones de Stack y no han llegado a ninguna parte.