How do I resolve Web API controllers using Autofac in a mixed Web API and MVC application?

34,294

Solution 1

nemesv's guidance did the trick

builder.RegisterApiControllers(Assembly.GetExecutingAssembly())

Calling builder.RegisterApiControllers before calling builder.Build()

Solution 2

I would suggest the following to make this work in your application with both MVC and WebApi.

First your project will need to have references to the following

  • Autofac
  • Autofac.WebApi
  • Autofac.Mvc5 (change the number at the end to match your aspnet mvc version)

Then in your Autofac registration you would need the following which will Register both MVC and WebApi Controllers and any other registrations you require. Then attach the Container to both the MVC DI and the WebApi DI.

var builder= new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly()); //Register MVC Controllers
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); //Register WebApi Controllers
//Register any other components required by your code....

var container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //Set the MVC DependencyResolver
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver((IContainer)container); //Set the WebApi DependencyResolver

I hope this helps.

Share:
34,294
progrAmmar
Author by

progrAmmar

Software Engineer working with Microsoft .NET technologies. Love working with C#.

Updated on October 27, 2020

Comments

  • progrAmmar
    progrAmmar over 3 years

    Hi I have an MVC application where I have defined some dependencies to my Web API.

    public class AutofacWebApiDependenceResolver : IDependencyResolver
    {
        private readonly IComponentContext container;
        public AutofacWebApiDependenceResolver(IContainer container)
        {
    
         if (container == null)
         {
             throw new ArgumentNullException("container");
         }
         this.container = container;
        }
    
        public object GetService(Type serviceType)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException("serviceType");
            }
            var ret = this.container.ResolveOptional(serviceType) ;
            return ret;
        }
        public IEnumerable<object> GetServices(Type serviceType)
        {            
            if (serviceType == null)
            {
                throw new ArgumentNullException("serviceType");
            }            
            Type enumerableType = typeof(IEnumerable<>).MakeGenericType(serviceType);
            var ret = (IEnumerable<object>)this.container.ResolveOptional(enumerableType);
            return ret;
        }
    }
    

    Then in my bootstrapper class I am calling it in Application_Start as follows:

    GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependenceResolver((IContainer)container);
    

    When I debug the code, I can see there are registrations of all services with my DependencyResolver, but I am still getting the following error:

    An error has occurred.Type 'WebApp.Controllers.AuthenticateController' does not have a default constructor

    Here is the code to my controller:

    public class AuthenticateController : ApiController
    {
        private readonly IFormsAuthenticationService formsAuthenticationService;
        private readonly IMemberShipProvider memberShip;
        private readonly IDataService dataService;
    
        public AuthenticateController(
            IMemberShipProvider memberShip,
            IFormsAuthenticationService formsAuthenticationService, IDataService dataService)
        {
            this.memberShip = memberShip;
            this.formsAuthenticationService = formsAuthenticationService;
            this.dataService= dataService;
         }
    
    }
    

    How can I bring parameters to the api controllers. The Simple controllers are working fine.