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,
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
I'm using Unity
of version 4.0.1
and in my case the nested dependency Repository
have had two public constructors and Unity hasn't managed to choose the parameterless constructor.
Thus, I've just specified the other one as protected to quickly solve the issue.
public Repository() : this( ... ) { ... }
// if need to make public, make sure that the dependency injection container
// will choose the parameterless constructor;
// Unity has had issues with that by default
protected Repository(DbContext context) : base() { ... }
IMO, Unity could have managed to find the "possible to call" constructor - as it had no DbContext (or any derived context) registered.
Please note that by default Unity
chooses a constructor with the maximum number of arguments.
So yes, it's also possible to decorate the proper constructor with InjectionConstructorAttribute
as it's described here and here - but I even don't have a Unity
reference in my data access layer (and don't want to).
Please tell me if such behavior has changed in the later versions.
Unfortunately none of these answers worked for me. I had already used the method offered by smoksnes by following the steps described here: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection
My issue was fixed by using the web api specific unity package (Unity.AspNet.WebApi) rather than the general .net package as described on the Microsoft guide.
Be sure that any nested types which are also injected are being resolved correctly. You will get error message on the controller level even if nested types are resolved incorrectly.
One more possible investigation path and cause for this issue. I set breakpoints on my global exception handler and looked into the nested exception property on my exception instance. I got the error does not have an accessible constructor which was true because the type I wanted to inject did have a private constructor (I was refactoring a singleton).