Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use named registration in autofac with MVC controller injection integration

I have autofac set up to do dependency injection of my asp.net MVC controllers, like so:

System.Web.Mvc.DependencyResolver
                   .SetResolver(new AutofacDependencyResolver(container));

And it is working fine. However, I have several implementations of an interface (say, IFoo) that I want to register as named instances:

builder.Register<Bar>(c => new Bar()).Named<IFoo>("bar");
builder.Register<Baz>(c => new Baz()).Named<IFoo>("baz");
...

And I have several controllers which take an IFoo in their constructor. But each controller needs a different concrete implementation of IFoo. How can I tell autofac which controller needs "bar" and which needs "baz"?

like image 217
Gabe Moothart Avatar asked Mar 01 '12 22:03

Gabe Moothart


People also ask

How do I register with Autofac?

First thing you need to do in order to use a container like Autofac is register all your dependencies. In Autofac you can do that a few ways but all of them rely on using the a ContainerBuilder . The ContainerBuilder relies on extension methods so make sure you have a using statement for the Autofac namespace.

Does MVC use dependency injection?

The Dependency Injection (DI) Design PatternThe Dependency Resolver in ASP.NET MVC can allow you to register your dependency logic somewhere else (e.g. a container or a bag of clubs). The advantages of using Dependency Injection pattern and Inversion of Control are the following: Reduces class coupling.


1 Answers

You can register (actually re-register if you are using builder.RegisterControllers()) your controllers with the parameter which will be used during resolve:

builder.RegisterType<SomeController>()
       .WithParameter(ResolvedParameter.ForNamed<IFoo>("bar"));
builder.RegisterType<OtherController>()
       .WithParameter(ResolvedParameter.ForNamed<IFoo>("baz"));

If a controller needs multiple IFoo you can specify the resolve parameter e.g. with name (with a little bit extra syntax, but you can hide it behind an extension method):

builder.RegisterType<ComplexController>().WithParameters(new [] {
 new ResolvedParameter((p,c) => p.Name == "bar",(p,c) => c.ResolveNamed<IFoo>("bar")),
 new ResolvedParameter((p,c) => p.Name == "baz",(p,c) => c.ResolveNamed<IFoo>("baz"))
});

public class ComplexController: Controller
{
    public ComplexController(IFoo baz, IFoo bar)
    {
         //...
    }
}
like image 109
nemesv Avatar answered Sep 28 '22 01:09

nemesv