I am using the Unity.WebApi NuGet package (Unity 4.0.1 and Unity.WebApi 5.2.3) in an ASP.NET WebApi solution. The issue I am facing is that when attempting to run the code, I get the error: Make sure that the controller has a parameterless public constructor
. I've searched similar threads here, but I couldn't find any thread that matched my issue.
Please don't just say "Add a parameterless constructor" because it shows you obviously have no clue what IoC is and why that statement makes absolutely no sense and defeats the purpose of IoC. I say this because I saw this on a lot of the other threads I've looked at thus far.
This is my Startup.cs (I'm using Owin, so I do not have a Global.asax):
public void Configuration(IAppBuilder app) {
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
// Registering unity stuff
UnityConfig.RegisterComponents();
app.UseWebApi(config);
}
This is my UnityConfig.cs:
public static class UnityConfig {
public static void RegisterComponents() {
var container = new UnityContainer();
// Register controller
container.RegisterType<MyController>();
// Register interface
container.RegisterType<IService, Service>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
This is my API Controller:
public class MyController : ApiController {
private IService service
public MyController(IService service) {
this.service = service;
}
public IHttpActionResult Get() {
return Ok("All systems go!");
}
}
EDIT
I took the using statements out because people are having a hard time understanding that the issue occurs whether or not the using statements are there.
In my experience there's 2 different scenarios when this occur.
1.
Make sure that all parameters in the Service
constructor can be resolved. Does it have any dependencies that you haven't registered?
Make sure that the controller has a parameterless public constructor in Unity
2. Make sure to register Unity with Web API. Like so:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Routes and other stuff here...
var container = IocContainer.Instance; // Or any other way to fetch your container.
config.DependencyResolver = new UnityDependencyResolver(container);
}
}
Examples here:
Injecting Dependency into Web API Controller
http://codeclimber.net.nz/archive/2015/02/20/Using-Entity-Framework-within-an-Owin-hosted-Web-API-with.aspx
EDIT 1:
As @NightOwl888 mentioned in the comments, you should not dispose the container. The registrations are registered on the container, and when the container is disposed it will not know how to resolve the dependencies. It may result in the error you are seeing.
EDIT 2:
Since you're using Owin you should be able to do something like this:
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.DependencyResolver = new UnityDependencyResolver(
UnityConfig.GetConfiguredContainer());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
And update your UnityConfig to this:
public static class UnityConfig {
public static IUnityContainer GetConfiguredContainer() {
var container = new UnityContainer();
// Register controller
container.RegisterType<MyController>();
// Register interface
container.RegisterType<IService, Service>();
//This is done in Startup instead.
//GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
return container;
}
}
From this source: How to use DI container when OwinStartup
http://damienbod.com/2013/10/01/self-host-webapi-with-owin-and-unity/
In this method, the HttpConfiguration.DependencyResolver is set to a UnityDependencyResolver instance. This is required so that contructor injection can be used in the webApi controllers. The UnityDependencyResolver class is exactly the same as the Unity.WebApi.UnityDependencyResolver class. Unity.WebApi is not used because this is a self hosted OWIN application.
Set the DependencyResolver
to the HttpConfiguration
you created at Startup, not GlobalConfiguration.Configuration
and make sure all your services constructor are public, hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With