sanjosep43
sanjosep43

Reputation: 617

MVC 4 and autofac: DependencyResolutionException

I'm using the following code for registering all of my controllers:

protected override void Load(ContainerBuilder builder)
{
  builder.RegisterControllers(typeof(MvcApplication).Assembly)
           .OnActivated(a => a.Context.InjectUnsetProperties(a.Instance))
           .OnActivating(InjectInvoker);
}
private static void InjectInvoker(IActivatingEventArgs<object> obj)
{
    var invoker = obj.Context.ResolveOptional<IActionInvoker>();
    if (invoker != null)
    {
        ((Controller)obj.Instance).ActionInvoker = invoker;
    }
}

but now I have a controller that takes 2 interfaces of the same kind:

        builder.Register(c => new RestClient(Url1))
            .Named<IRestClient>("Url1")
           .InstancePerLifetimeScope();

        builder.Register(c => new RestClient(Url2))
            .Named<IRestClient>("Url2")
           .InstancePerLifetimeScope();

    public HomeController(IRestClient r1, IRestClient r2)

I get the following error: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Site.Controllers.HomeController' can be invoked with the available services and parameters: Cannot resolve parameter 'RestSharp.IRestClient r1' of constructor 'Void .ctor(RestSharp.IRestClient, RestSharp.IRestClient)'. Which I did expect, so then I've tried adding the following code:

        builder.Register(
            c =>
            new HomeController(
                               c.ResolveNamed<IRestClient>("Url1"),
                               c.ResolveNamed<IRestClient>("Url2")))
                             .As<IController>()
                             .InstancePerLifetimeScope();

which then I got the same error again.

so what is the correct way to register a controller in the kind of situation? thanks.

Upvotes: 1

Views: 1436

Answers (1)

nemesv
nemesv

Reputation: 139758

You need to register your controller without the .As<IController>() (or you need to use .AsSelf() but this is default setting).

You need to this because the framework will try to resolve your Controller with using the concrete type HomeController and not the IController interface (so the RegisterControllers method register all the controller with .AsSelf() internally).

So the following registration should work

builder.Register(
    c =>
        new HomeController(
            c.ResolveNamed<IRestClient>("Url1"),
            c.ResolveNamed<IRestClient>("Url2")))
        .InstancePerLifetimeScope();

Note: you should have this call after the RegisterControllers call.

Upvotes: 1

Related Questions