Unity IoC does not inject dependency in Web API Controller

I am very new to using Unity, but my problem is that whenever I call my web service, I get an exception indicating that

"Make sure the controller has a hassle-free public constructor"

I have been following several tutorials and I am still having the same problem.

In the Register function of my WebApiConfig class, I have

var container = new UnityContainer(); container.RegisterType<IValidator, Validator>(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<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(); } } 

I have not registered any controllers, as each tutorial claims that I do not 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 on what I might be doing wrong? Thank!

EDIT 1: Here is the "implementation" of the Validator class. This is pretty empty because I didn’t want to introduce an error here until I solved the Unity problem.

 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 full error response I get when I try to invoke the api web route using Fiddler

{"message": "An error occurred.", "exceptionMessage": "An error occurred while trying to create a controller of type" Controller. "Make sure that the controller has stepless publication. Constructor" "ExceptionType.": "System.InvalidOperationException" "StackTrace" : "in the System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create (HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, type ControllerType) in System.Web.Http.Controllers.HttpHttp.ControlPerControl.ControllerControllerControllerControllerControllerControllerControllerControllerControllerControllerControllerControllerControllerController.ControllerController. .d__1.MoveNext () "" InnerException ": {" message ":" error ".," exceptionMessage ":" Type "Project.Controller 'does not have a default constructor" "ExceptionType": "System.ArgumentException", " Sta ckTrace ":" in System.Linq.Expressions.Expression.New (type type) in System.Web.Http.Internal.TypeActivator.Create [TBase] (instanceType type) in System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstatorOrActArAct HttpRequestMessage request, Type controllerType, Func`1 & activator) under System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create (HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, type ControllerType) "}}

+21
c # asp.net-web-api unity-container
Apr 13 '15 at 17:08
source share
4 answers

So, after several hours of bumping my head against the wall, I found that this wasn’t working because the OWIN / Katana Startup.cs class was in my project. Now I don’t know exactly what is going on here, so more information would be great.

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

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

It seems that the code is first run through the WebApiConfig registration function, and THEN overrides the HttpConfiguration object with the one that was generated in the Startup.cs file. I needed to move my container to make it work.

Sorry I didn’t bring up OWIN stuff before. This is completely new to me, and I did not understand that it was relevant. Hope this saves someone the pain I just experienced.

+25
Apr 13 '15 at 20:15
source share

A Unity container can be deleted because it is defined only in the scope of your WebApiConfig.Register() method. If you define your container as a Global member that will support your container for the duration of the application, it should work.

Edit: also remember to recycle the container on Application_End.

+1
Apr 13 '15 at 18:29
source share
  • Install Unity.mvc5 and Unity.WebApi in the project via nuget package
  • Specify the full namespace as follows

Example:

 public static class UnityConfig { public static void RegisterComponents() { var container = new UnityContainer(); // register all your components with the container here // it is NOT necessary to register your controllers // eg container.RegisterType<ITestService, TestService>(); DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container)); GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); } } 
0
Dec 10 '18 at 14:35
source share

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

EDIT: Just noted that the accepted answer does 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); } } 
-one
Nov 17 '16 at 21:56
source share



All Articles