Unity IoC does not inject dependency into Web API Controller

匿名 (未验证) 提交于 2019-12-03 01:22:02

问题:

I'm very new to using Unity, but my problem is that whenever I call my web service, I get an exception stating that

"Make sure that the controller has a parameterless public constructor"

I've followed multiple tutorials and I still get the same issue.

In the Register function of my WebApiConfig class, I have

var container = new UnityContainer(); container.RegisterType(new HierarchicalLifetimeManager()); config.DependencyResolver = new UnityResolver(container); 

Here is my UnityResolver class

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 GetServices(Type serviceType)     {         try         {             return container.ResolveAll(serviceType);         }         catch (ResolutionFailedException)         {             return new List();         }     }      public IDependencyScope BeginScope()     {         var child = container.CreateChildContainer();         return new UnityResolver(child);     }      public void Dispose()     {         container.Dispose();     } } 

I have not registered any controllers, as every tutorial claims that I don't need to do this. Here is my actual controller

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

Does anyone have any ideas as to what I can be doing wrong? Thanks!

EDIT 1: Here is the "implementation" of the Validator class. It's pretty empty, because I didn't want to introduce a bug here until I resolved the Unity issue.

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: Here is the entire error response I get when I attempt to call the web api route using Fiddler

{"message":"An error has occurred.","exceptionMessage":"An error occurred when trying to create a controller of type 'Controller'. Make sure that the controller has a parameterless public constructor.","exceptionType":"System.InvalidOperationException","stackTrace":" at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()","innerException":{"message":"An error has occurred.","exceptionMessage":"Type 'Project.Controller' does not have a default constructor","exceptionType":"System.ArgumentException","stackTrace":" at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"}}

回答1:

So, after hours of banging my head against a wall, I've found that this wasn't working because I had an OWIN/Katana Startup.cs class in my project. Now I don't know exactly what's going on here, so any more information would be great.

Basically, since I was using OWIN/Katana, I had a Startup.cs file that created a new HttpConfiguration object and configured it, similar to how it's done in the WebApiConfig.cs class.

private void ConfigureWebApi(HttpConfiguration config) {     config.MapHttpAttributeRoutes();     var container = new UnityContainer();     container.RegisterType();     config.DependencyResolver = new UnityDependencyResolver(container);      var jsonFormatter = config.Formatters.OfType

It looks like the code first runs through the WebApiConfig's Register function, and THEN overrides that HttpConfiguration object with the one generated in the Startup.cs file. I had to move my container setup stuff here in order for it to work.

Sorry that I didn't bring up the OWIN stuff before. This is fairly new to me and I didn't realize it was relevant. Hopefully this saves someone else the pain that I've just been through.



回答2:

Your Unity container is probably getting disposed because it's only defined in the scope of your WebApiConfig.Register() method. If you define your container as a member of Global, which will keep your container around for the lifetime of the app, it should work.

Edit: also don't forget to dispose the container on Application_End.



回答3:

I know this is an old post but since I just ran into the same problem, the solution was to simply pass the config object to the Unity registration function and use the DependencyResolver from that instance:

EDIT: Just noted that the accepted answer does exacly this... Sorry for the spam ;-)

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!