Has anyone had any success running using an IoC container to inject dependencies into ASP.NET WebAPI controllers? I cannot seem to get it to work.
This is what I'm doing now.
In my global.ascx.cs
:
public static void RegisterRoutes(RouteCollection routes)
{
// code intentionally omitted
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
IUnityContainer container = BuildUnityContainer();
System.Web.Http.GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
t =>
{
try
{
return container.Resolve(t);
}
catch (ResolutionFailedException)
{
return null;
}
},
t =>
{
try
{
return container.ResolveAll(t);
}
catch (ResolutionFailedException)
{
return new System.Collections.Generic.List<object>();
}
});
System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
BundleTable.Bundles.RegisterTemplateBundles();
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer().LoadConfiguration();
return container;
}
My controller factory:
public class UnityControllerFactory : DefaultControllerFactory
{
private IUnityContainer _container;
public UnityControllerFactory(IUnityContainer container)
{
_container = container;
}
public override IController CreateController(System.Web.Routing.RequestContext requestContext,
string controllerName)
{
Type controllerType = base.GetControllerType(requestContext, controllerName);
return (IController)_container.Resolve(controllerType);
}
}
It never seems to look in my unity file to resolve dependencies, and I get an error like:
An error occurred when trying to create a controller of type
'PersonalShopper.Services.WebApi.Controllers.ShoppingListController'.
Make sure that the controller has a parameterless public constructor.
at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpControllerContext
controllerContext, Type controllerType)
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContext
controllerContext, HttpControllerDescriptor controllerDescriptor)
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController(HttpControllerContext
controllerContext, String controllerName)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage
request, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage
request, CancellationToken cancellationToken)
Controller looks like:
public class ShoppingListController : System.Web.Http.ApiController
{
private Repositories.IProductListRepository _ProductListRepository;
public ShoppingListController(Repositories.IUserRepository userRepository,
Repositories.IProductListRepository productListRepository)
{
_ProductListRepository = productListRepository;
}
}
My unity file looks like:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="PersonalShopper.Repositories.IProductListRepository, PersonalShopper.Repositories" mapTo="PersonalShopper.Implementations.MongoRepositories.ProductListRepository, PersonalShopper.Implementations" />
</container>
</unity>
Note that I don't have a registration for the controller itself because in previous versions of mvc the controller factory would figure out that the dependencies needed to be resolved.
It seems like my controller factory is never being called.
See Question&Answers more detail:
os