Search code examples
c#asp.net-web-apidependency-injectionasp.net-mvc-5autofac

Unable to configure autofac in Web Api project


I am facing a weird issue that has been making me confused during the last two days. As I have researched and tried different solution it is not solved yet.

Autofac is used as DI container. The solution contains several projects including a ASP.NET MVC 5 and Web API. We are unable to configure and register Autofac in the API project, while it is working properly on web project.

I have tried several solutions such as the links below but none of them works.

https://stackoverflow.com/a/15910758/7855321

https://stackoverflow.com/a/36063722/7855321

https://stackoverflow.com/a/12277002/7855321

...

I am facing the error of " An error occurred when trying to create a controller of type 'OperationController'. Make sure that the controller has a parameterless public constructor".

The codes are provided below

Startup.cs

public void Configuration(IAppBuilder app)
        {
            var httpConfig = new HttpConfiguration();

            ConfigureOAuth(app);

            WebApiConfig.Register(httpConfig);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

            RegisterMappers();

            var builder = new ContainerBuilder();
            //builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
            builder.RegisterApiControllers(typeof(OperationController).Assembly).PropertiesAutowired();

            builder.RegisterAssemblyTypes(Assembly.Load("PSMS.Repository"))
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope();

            builder.RegisterType<PsmsDbContext>().InstancePerRequest();
            builder.RegisterType<TransactionDbContext>().InstancePerRequest();
            builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).InstancePerDependency();

            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            app.UseWebApi(httpConfig);
        }

OperationController.cs

[RoutePrefix("api/Operation")]
public class OperationController : ApiController
{
    private readonly IUserRepository _userRepository;
    private readonly ITerminalsRepository _terminalsRepository;
    private readonly ITaskHeaderRepository _taskHeaderRepository;

    public OperationController(
        IUserRepository userRepository,
        ITerminalsRepository terminalsRepository,
        ITaskHeaderRepository taskHeaderRepository)
    {
        _userRepository = userRepository;
        _terminalsRepository = terminalsRepository;
        _taskHeaderRepository = taskHeaderRepository;
    }

[Authorize]
    [Route("~/api/Operation/FindTerminal")]
    [HttpPost]
    public IHttpActionResult FindTerminal(GetTerminalInputDto inputDto)
    {
        if (string.IsNullOrEmpty(inputDto.TerminalNo))
            return ResponseMessage(new HttpResponseMessage(HttpStatusCode.NotAcceptable));

        var userPersonnel = _userRepository.GetPersonnelUser(inputDto.TerminalNo);

        var terminal = _terminalsRepository.SearchTerminals(new TerminalsSearchContext
        {
            Terminal = new Terminals
            {
                TerminalNo = inputDto.TerminalNo
            },
            PersonnelId = userPersonnel.PersonnelId ?? 0,
            PersonnelType = (Enumeration.PersonnelTypeEnum)userPersonnel.PersonnelTypeId,
            Take = 1,
            Skip = 0
        }).FirstOrDefault();

        var result = new GetTerminalOutputDto(terminal);
        return Json(result);
    }
}

I again repeat, the same config works in the ASP.NET MVC project. Any help is appreciated


Solution

  • You're using OWIN, not classic Web API setup. Per the docs:

    A common error in OWIN integration is use of the GlobalConfiguration.Configuration. In OWIN you create the configuration from scratch. You should not reference GlobalConfiguration.Configuration anywhere when using the OWIN integration.

    Switch this:

    GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    

    to

    httpConfig.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    

    Also, not sure why you're setting the MVC dependency resolver. For Web API you don't need:

    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));