Steve Wash
Steve Wash

Reputation: 986

Autofac not resolving Type and Named Parameter for ApiController

I have three different applications that all build with the same business layer/data layer. I'm adding a IUserNameProvider to the IUnitOfWork class that is used by all three applications. Because the each application get the User names using a different method, I created the IUserNameProvider and I'm injecting the appropriate implementation using Autofac.

This seems like it should be fairly straightforward code, but I can't get it configured correctly for the Web API application. Similar code is working fine in the console application

My Global.asax.cs

protected void Application_Start()
{
    var builder = new ContainerBuilder();

    builder.RegisterType<WebAPIGetUser>().As<SSEMPA.DataAccess.Infrastructure.IUserNameProvider>();
    builder.RegisterType<UnitOfWork>().As<IUnitOfWork>()
     .WithParameter("connectionString", ConfigurationManager.ConnectionStrings["MyDataContex"].ConnectionString);

    //other type registrations ...

    DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));

    // other registrations ....
}

My UnitOfWork constructor

public class UnitOfWork : IUnitOfWork
{
    private MyDataContext dataContext;

    public UnitOfWork(IUserNameProvider userNameProvider, string connectionString)
    {
        dataContext = new MyDataContext (connectionString, userNameProvider);
    }

    ...
}

My ApiController

public class AgencyApiController : ApiController
{
    private readonly IUnitOfWork _unitOfWork;

    public AgencyApiController(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    ...
}

When the API gets hit, it throws the following error:

<Error>
    <Message>An error has occurred.</Message>
    <ExceptionMessage>An error occurred when trying to create a controller of type 'AgencyApiController'. Make sure that the controller has a parameterless public constructor.
    </ExceptionMessage>
    <ExceptionType>System.InvalidOperationException</ExceptionType>
    <StackTrace>at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
    </StackTrace>
    <InnerException>
        <Message>An error has occurred.</Message>
        <ExceptionMessage>None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'SSEMPA.DataAccess.Infrastructure.UnitOfWork' can be invoked with the available services and parameters: Cannot resolve parameter 'SSEMPA.DataAccess.Infrastructure.IUserNameProvider userNameProvider' of constructor 'Void .ctor(SSEMPA.DataAccess.Infrastructure.IUserNameProvider , System.String)'.
        </ExceptionMessage>
        <ExceptionType>Autofac.Core.DependencyResolutionException</ExceptionType>

I've tried using named parameters for both the IUserNameProvider and connections string, but that didn't change anything. It seems like this should work, so I must be missing something small.

Thanks for looking at this.

Upvotes: 2

Views: 860

Answers (1)

Jeff Ogata
Jeff Ogata

Reputation: 57823

There is additional configuration and setup you need to do for WebAPI, beyond what you do for a console application. Take a look at the docs here for instructions: Autofac Web Api Integration

Upvotes: 2

Related Questions