unity tutorial net mvc injection dependency container asp c# unity-container asp.net-web-api

c# - tutorial - Unity IoC no inyecta dependencia en el controlador de la API web



web api 2 unity (3)

Su contenedor de Unity probablemente esté siendo eliminado porque solo está definido en el alcance de su método WebApiConfig.Register() . Si define su contenedor como miembro de Global, que mantendrá su contenedor durante toda la vida de la aplicación, debería funcionar.

Editar: tampoco olvide desechar el contenedor en Application_End.

Soy muy nuevo en el uso de Unity, pero mi problema es que cada vez que llamo a mi servicio web, recibo una excepción que indica que

"Asegúrese de que el controlador tenga un constructor público sin parámetros"

He seguido varios tutoriales y todavía tengo el mismo problema.

En la función Registrar de mi clase WebApiConfig, tengo

var container = new UnityContainer(); container.RegisterType<IValidator, Validator>(new HierarchicalLifetimeManager()); config.DependencyResolver = new UnityResolver(container);

Aquí está mi clase UnityResolver

using Microsoft.Practices.Unity; using System; using System.Collections.Generic; using System.Web.Http.Dependencies; public class UnityResolver : IDependencyResolver { protected IUnityContainer container; public UnityResolver(IUnityContainer container) { if (container == null) { throw new ArgumentNullException("container"); } this.container = container; } public object GetService(Type serviceType) { try { return container.Resolve(serviceType); } catch (ResolutionFailedException) { return null; } } public IEnumerable<object> GetServices(Type serviceType) { try { return container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List<object>(); } } public IDependencyScope BeginScope() { var child = container.CreateChildContainer(); return new UnityResolver(child); } public void Dispose() { container.Dispose(); } }

No he registrado ningún controlador, ya que cada tutorial afirma que no necesito hacer esto. Aquí está mi controlador real

public class Controller: ApiController { private IValidator _validator; public Controller(IValidator validator) { this._validator = validator; } [HttpPost] public void ReceiveIPN() { } }

¿Alguien tiene alguna idea de lo que puedo estar haciendo mal? ¡Gracias!

EDIT 1: Aquí está la "implementación" de la clase Validator. Está bastante vacío, porque no quería introducir un error aquí hasta que resolviera el problema de Unity.

using System; using System.Collections.Generic; using System.Linq; using System.Web; public class Validator: IValidator { public bool ValidateIPN(string body) { throw new NotImplementedException(); } }

EDIT 2: Aquí está toda la respuesta de error que recibo cuando intento llamar a la ruta de la API web usando Fiddler

{"mensaje": "Ha ocurrido un error". "exceptionMessage": "Ha ocurrido un error al intentar crear un controlador de tipo ''Controlador''. Asegúrese de que el controlador tenga un constructor público sin parámetros.", "exceptionType": "System.InvalidOperationException", "stackTrace": "en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create (solicitud HttpRequestMessage, HttpControllerDescriptor controllerDescriptor, tipo controllerType) en System.Web.Http.Controllers.HttpControllerDescriptor.CreateController (solicitud HttpRequestMessage) en System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext () "," innerException ": {" message ":" Ha ocurrido un error. "," ExceptionMessage ":" Tipo ''Project.Controller'' no tiene un valor predeterminado constructor "," exceptionType ":" System.ArgumentException "," stackTrace ":" en System.Linq.Expressions.Expression.New (Tipo de tipo) en System.Web.Http.Internal.TypeActivator.Create [TBase] (Tipo instanceType ) en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceO rActivator (solicitud HttpRequestMessage, tipo controllerType, Func`1 y activador) en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create (solicitud HttpRequestMessage, HttpControllerDescriptor controllerDescriptor, Type controllerType) "}}


Entonces, después de horas de golpear mi cabeza contra una pared, descubrí que esto no funcionaba porque tenía una clase OWIN / Katana Startup.cs en mi proyecto. Ahora no sé exactamente qué está pasando aquí, por lo que cualquier otra información sería genial.

Básicamente, dado que estaba usando OWIN / Katana, tenía un archivo Startup.cs que creaba un nuevo objeto HttpConfiguration y lo configuraba, de forma similar a cómo se hace en la clase WebApiConfig.cs.

private void ConfigureWebApi(HttpConfiguration config) { config.MapHttpAttributeRoutes(); var container = new UnityContainer(); container.RegisterType<IValidator, Validator>(); config.DependencyResolver = new UnityDependencyResolver(container); var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter().First(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }

Parece que el código se ejecuta primero a través de la función de registro de WebApiConfig y, a continuación, anula ese objeto HttpConfiguration con el generado en el archivo Startup.cs. Tuve que mover mi configuración de contenedor aquí para que funcione.

Perdón por no haber mencionado las cosas de OWIN antes. Esto es bastante nuevo para mí y no me di cuenta de que era relevante. Espero que esto le ahorre a otra persona el dolor por el que he pasado.


Sé que esta es una publicación anterior, pero como me encontré con el mismo problema, la solución fue simplemente pasar el objeto config a la función de registro de Unity y usar DependencyResolver desde esa instancia:

EDITAR: Acabo de señalar que la respuesta aceptada hace exactamente esto ... Lo siento por el correo no deseado ;-)

public static class UnityConfig { public static void Register(HttpConfiguration config) { var container = new UnityContainer(); // register your services here... // replace... /* GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); */ // with this: config.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); } }