Использовать названную регистрацию в autofac с интеграцией впрыска контроллера MVC

У меня есть autofac, настроенный для выполнения зависимостей моих контроллеров MVC asp.net, например:

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

И он работает нормально. Тем не менее, у меня есть несколько реализаций интерфейса (скажем, IFoo), который я хочу зарегистрировать как именованные экземпляры:

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

И у меня есть несколько контроллеров, которые принимают IFoo в своем конструкторе. Но каждый контроллер нуждается в другой конкретной реализации IFoo. Как я могу сказать autofac, какой контроллер нуждается в "баре" и который нуждается в "baz"?

Ответ 1

Вы можете зарегистрировать (фактически перерегистрировать, если используете builder.RegisterControllers()) свои контроллеры с parameter, которые будут использоваться во время разрешения:

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

Если контроллеру требуется несколько IFoo, вы можете указать параметр разрешения, например. с именем (с немного дополнительным синтаксисом, но вы можете скрыть его за методом расширения):

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)
    {
         //...
    }
}