How do I get self host to work with IoC for Web-Api integration tests?
asp.net-web-api, autofac, dependency-injection, inversion-of-control, self-hosting
Solution
It looks like you have forgotten to register the controller with the container and Web API is trying to create the instance for you.
var builder = new ContainerBuilder();
// Register API controllers using assembly scanning.
builder.RegisterApiControllers(typeof(ValuesController).Assembly);
var container = builder.Build();
You can also register the individual controller if required.
Problem
I've taken hints from here to come up with this integration test for my new Web Api project. I'm trying to build a rest web service and I have a helper client that I plan to release to API consumers. That's the `ExampleClientHelper` type there. Oh and btw, this all wires up to the `ValuesController` that's provided with the project template for a MVC4 Web Api Visual Studio project - I'm keeping things simple while I nut this out. `ExampleClientHelper` replaces all the request/response in the aforementioned reference example. It's using RestSharp internally. ``` [Test] [Ignore] public void ValuesHelper_ShouldReturn_value1_And_value2_AsTypedObject() { // IoC prep var builder = new ContainerBuilder(); var container = builder.Build(); // web server prep var baseUri = new Uri("http://localhost:8080"); var config = new HttpSelfHostConfiguration(baseUri); config.DependencyResolver = new AutofacWebApiDependencyResolver(container); // yes, the routing needs to be copied over. it's not compatible with the MVC routes config.Routes.MapHttpRoute("Api", "api/{controller}/{id}", new { id = RouteParameter.Optional, namespaces = new[] { typeof(ValuesController).Namespace } }); // start the server and make a request new HttpSelfHostServer(config) .OpenAsync() .ContinueWith(task => { var client = new ExampleClientHelper(baseUri); var values = client.GetValues(); // then test the response Assert.AreEqual("value1", values.ElementAt(0)); Assert.AreEqual("value2", values.ElementAt(1)); }) .Wait(); } ``` The code above works fine as long as you don't modify `ValuesController`. ie. it remains having an implicit parameterless constructor. The problem I'm having is that the self host server can't seem to instantiate my `ValuesController` when I modify it to require a dependency. The issue is, I get the same exception from the response from my helper client whether I wire up the Autofac DependencyResolver or not. This is what is returned in the Content of the response, nicely formatted as JSON thanks to RestSharp: {"ExceptionType":"System.ArgumentException","Message":"Type 'Embed.ECSApi.RestServer.Controllers.ValuesController' does not have a default constructor","StackTrace":" at System.Linq.Expressions.Expression.New(Type type)\r\n at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"} So clearly the self host server is trying to create `ValuesController` but it can't. Why? I thought I wired up the DependencyResolver properly. I'm expecting to get an Autofac exception instead which complains about my dependency that I haven't configured.