5

I'm trying to get Autofac to work with WebApi. I have my ApiControllers in a separate project from the main web project.

InventorySystem.Web.UI InventorySystem.Web.Api.Controllers

Whenever i try to browse to an api route i get the response:

<Exception xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ExceptionType>System.ArgumentNullException</ExceptionType>
    <Message>Value cannot be null. Parameter name: value</Message>
    <StackTrace>
at System.Web.Http.Controllers.HttpControllerContext.set_Controller(IHttpController value)
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContext controllerContext, HttpControllerDescriptor controllerDescriptor)
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController(HttpControllerContext controllerContext, String controllerName)
at Autofac.Integration.WebApi.AutofacControllerFactory.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)
    </StackTrace>
</Exception>

When i step through the Autofac code I see that my controller has been registered, but the AutofacControllerActivator.Create() returns null. Specifically the line return (ResolutionExtensions.ResolveOptional(scope, controllerType) as IHttpController);

The autofac code: string binDirectory = Path.Combine(HttpRuntime.AppDomainAppPath, "bin");

        var builder = new ContainerBuilder();

        builder.ConfigureWebApi(GlobalConfiguration.Configuration);

        builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
        builder.RegisterApiControllers(Assembly.LoadFile(Path.Combine(binDirectory, "InventorySystem.Web.Api.dll"))).PropertiesAutowired();
        builder.RegisterFilterProvider();            

        var container = builder.Build();

        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new AutofacWebApiDependencyResolver(container));

Am i missing something?

Thanks

2
  • Is the assembly location you are providing to RegisterAPIControllers definitely correct? I got the same error when I made a mistake with my assembly name. Commented Apr 29, 2012 at 13:27
  • @Gavin yes, because my apicontroller does get registerred. It's just the resolving which seems to fail. Commented Apr 29, 2012 at 14:45

4 Answers 4

2

The RegisterApiControllers registration extension looks for types that implement the IHttpController interface and have a name that ends with "Controller". Do your controller class names have a suffix of "Controller"?

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, it implements IHttpController eventually and the name also ends with Controller. Also, if i put my api controller in the main project it works fine. I'll try to create a test project to demonstrate the problem.
I'm also not sure if lifetimeScope.ResolveOptional(controllerType) returns null or the cast to IHttpController. Any way I could check this easily?
(we work at the same place, thus I have access to the code): builder.RegisterApiControllers(typeof(InventorySystem.Web.Api.Controllers.InventoryController).Assembly).PropertiesAutowired(); fixed the issue, however we would like to be able to use Assembly.Load so we can switch between implementations and what not. Please advice why we see this behavior. (And: Thanks for the Autofac integration module! We love Autofac and all that integrates well with it)
2

You might want to give a look at this SO question, where the other assembly is picked up starting from one of the references API Controllers.

Comments

0

Are you forgetting to register constructor dependencies for your Api controllers with the build container?

HostingEnvironment.MapPath("~/bin") is another good way to get the path to a file in the bin directory.

1 Comment

Unfortunately that did not help.
-1
var builder = new ContainerBuilder();   
builder.Update(container);
 var webApiResolver = new Autofac.Integration.WebApi.AutofacWebApiDependencyResolver(container);
    System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.