Timur Lemeshko
Timur Lemeshko

Reputation: 2879

Dependency error while resolving controller with autofac

I'm developing an ASP.MVC application. I use Autofac for DI. My controller PayrollCenterReportsController places at assembly 'LK.Reports.Services.WebApi.Module' and requires some serivce at constructor:

public class PayrollCenterReportsController : ODataControllerBase<PayrollCenterReports>
    {
        public PayrollCenterReportsController(IDataService<PayrollCenterReports> service)
            : base(service)
        {
        }
    }

I'm registering serivce at other assembly

public class MenaAutofacInitializer : IAutofacIntitializer
    {
        public void Initialize(ContainerBuilder builder)
        {
            ...

            builder.RegisterType<PayrollCenterReportsClientService>().As<IDataService<PayrollCenterReports>>();

            ...
        }
    }

and at Global.asax i use my initializer:

var builder = new ContainerBuilder();
new MenaAutofacInitializer().Initialize(builder);
var container = builder.Build();

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

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

SiteMaps.Loader = container.Resolve<ISiteMapLoader>();

But at page i get error:

An error has occurred. An error occurred when trying to create a controller of type 'PayrollCenterReportsController'. Make sure that the controller has a parameterless public constructor. System.InvalidOperationException 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.d__1.MoveNext() An error has occurred. Type 'LK.Reports.Services.WebApi.Module.Controllers.PayrollCenterReportsController' does not have a default constructor System.ArgumentException at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

The only way to resolve it is to use assembly with controller explicitly:

var a = typeof (PayrollCenterReportsController)

With this code Autofac resolve dependency and all fine.

loading assembly

assembly = Assembly.Load("LK.Reports.Services.WebApi.Module, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");

didn't help

Is there any way to resolve it without explitly using typeof(PayrollCenterReportsController) in Global.asax?

Upvotes: 0

Views: 1588

Answers (2)

Ross Kerr
Ross Kerr

Reputation: 153

I just ran into a similar error on my way to getting OData into an MVC5 project. The following steps helped me to get it up and running:

  1. Use the Autofac.WebApi2 nuget package, not the Autofac.WebApi package. (And uninstall Autofac.WebApi before adding WebApi2, this will save you from manually adding WebApi2 to the references.)

  2. Add a reference to the WebApi2 extensions in your Global.asax.cs (or wherever you're spinning up Autofac) with using Autofac.Integration.WebApi;

  3. MVC and WebApi use separate DI frameworks. For MVC, register your controllers with builder.RegisterControllers. For WebApi2 (OData) use builder.RegisterApiControllers.

  4. Finally, set your DI resolvers, one for MVC and one for WebApi2:

    DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); // MVC

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

Upvotes: 0

Cyril Durand
Cyril Durand

Reputation: 16187

If you want to avoid explicitly registering all you controllers you can use the RegisterControllers method

builder.RegisterControllers(typeof(MvcApplication).Assembly);

which can take more than one assembly :

builder.RegisterControllers(AppDomain.CurrentDomain.GetAssemblies());

You can find more information in the documentation : Register Controllers


By the way, instead of your custom IAutofacIntitializer interface I recommend using IModule. See documentation for more information

Upvotes: 1

Related Questions