21

I know it's been asked and answered before - the reason I'm asking is because (I think) I tried all suggested solutions to this problem but still can't resolve it.

I have an ASP.NET Web API 2.0 project. I have Autofac, Autofac.Mvc5 and Autofac.WebApi2 dependencies installed. When I try to call an API controller I get the following error:

An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor.

In my Global.asax I have a call to IocConfig.Config() which I have placed inside App_Start:

public static class IocConfig
{
    public static void Config()
    {
        var builder = new ContainerBuilder();

        builder.RegisterType<MyLogger>().As<IMyLogger>();

        builder.RegisterApiControllers(Assembly.GetCallingAssembly());
        builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);

        WebApiApplication.Container = builder.Build();

        DependencyResolver.SetResolver(
            new AutofacDependencyResolver(WebApiApplication.Container));
        GlobalConfiguration.Configuration.DependencyResolver =
             new AutofacWebApiDependencyResolver(WebApiApplication.Container);
    }
}

And this is the constructor for MyController:

public MyController(IMyLogger logger)

When I try to call it I get the specified error about the constructor. What am I missing?

Adrita Sharma
  • 21,581
  • 10
  • 69
  • 79
developer82
  • 13,237
  • 21
  • 88
  • 153

6 Answers6

25

I encountered this error as well and the root cause was that one of the Controller's dependencies wasn't registered correctly in Autofac.

The InnerException has the detail (in my case it was an Autofac.Core.DependencyResolutionException) and the ExceptionMessage included the detail of this dependency. Along the lines of:

"An error occurred during the activation of a particular registration... Cannot resolve parameter 'XXXX'

ScottB
  • 1,363
  • 2
  • 14
  • 24
  • 2
    this solved it! the inner exception was wrapping the real issue, a missing registration. – DanielV Dec 13 '18 at 12:04
  • FWIW: If you get no clues about which parameter it might be due to the constructor not being public. In my case the constructor was internal. Switched it to public and everything worked as it should. – LosManos Apr 27 '20 at 15:06
  • This pointed me to the right direction. Great tip! – Paulito.Bandito Mar 16 '21 at 19:12
15

Check this answer.
It helps me configure correct ContainerBuilder() for WebApi controllers.

If you are looking here a solution for such error you should check your DependencyResolver Configuration first.

I faced the same issue and the problem was that I was using Autofac code samples for ContainerBuilder() object for MVC controllers and not API.

My code for register both type of controllers (MVC and Api):

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly()); //Register MVC Controllers
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); //Register WebApi Controllers
builder.RegisterType<Type>().As<IType>();

var container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //Set the MVC DependencyResolver
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver((IContainer)container); //Set the WebApi DependencyResolver
kkost
  • 3,640
  • 5
  • 41
  • 72
3

Assembly.GetCallingAssembly() will return the calling assembly, not the assembly where your types is defined.

Assembly.GetCallingAssembly Method
Returns the Assembly of the method that invoked the currently executing method.

In order to make it works, you should use typeof(IocConfig).Assembly or Assembly.GetExecutingAssembly

Cyril Durand
  • 15,834
  • 5
  • 54
  • 62
  • 2
    I already tried `Assembly.GetExecutingAssembly` also tried you suggestion to try `typeof(IocConfig).Assembly` - still the same error – developer82 May 31 '16 at 11:15
1

You might be missing calling configuration from WebApiConfig.cs file:

IocConfigurator.ConfigureDependencyInjection(config);

ConfigureDependencyInjection can be like this:

public static void ConfigureDependencyInjection(HttpConfiguration config)
        {

            var builder = new ContainerBuilder();

            // Register your Web API controllers.
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            // OPTIONAL: Register the Autofac filter provider.
            builder.RegisterWebApiFilterProvider(config);

            // OPTIONAL: Register the Autofac model binder provider.
            builder.RegisterWebApiModelBinderProvider();

            // Set the dependency resolver to be Autofac.
            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

        }
Wasiqul Islam
  • 303
  • 3
  • 11
  • This is perhaps not recommended, but it worked like a charm on a legacy project. My constraint is that I'm not allowed to change how this project is initially set up so I couldn't get it to work properly via the startup file. Thanks! – Paulito.Bandito Mar 16 '21 at 19:10
0

I think you are missing registering autofac at app start code.

Use this:

protected void Application_Start()
{
    IocConfig.Config();
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
   BundleConfig.RegisterBundles(BundleTable.Bundles);
}

For more details, refer this blog http://www.codeproject.com/Articles/808894/IoC-in-ASP-NET-MVC-using-Autofac

error_handler
  • 1,191
  • 11
  • 19
  • As I wrote in original question "In my Global.asax I have a call to IocConfig.Config() which I have placed inside" - It even breaks in the configuration itself - so it definitely runs. – developer82 May 31 '16 at 09:56
  • it should be called inside Application_Start because this will be called once for the lifetime of the application domain. – error_handler May 31 '16 at 10:02
  • It is called once. It is as mentioned in the `Application_Start`. Also, moving the code outside the of it's own method directly to the `Application_Start` still doesn't work. – developer82 May 31 '16 at 11:18
-1

Open you ServiceModule File

Register the Interface and service name those are mentioned in controller.

Example are as below:-

builder.RegisterType().As();

Arjun Walmiki
  • 173
  • 1
  • 1
  • 13