Когда вы регистрируете несколько компонентов («классов»), предоставляющих один и тот же интерфейс («службу»), он последний среди побед . Это означает, что если у вас есть:
var builder = new ContainerBuilder();
builder.RegisterType<First>().As<IThing>();
builder.RegisterType<Second>().As<IThing>();
builder.RegisterType<Third>().As<IThing>();
var container = builder.Build();
Тогда, когда вы попытаетесь разрешить IThing
, всегда будет последним.
var thing = container.Resolve<IThing>();
Assert.IsType<Third>(thing); // this is true
Неважно, какие параметры вы передаете. Если вы разрешите один экземпляр вещи, он всегда будет последним в победах. Здесь нет «выбрать вещь на основе параметров, которые я передаю». И если подумать, это имеет смысл - с точки зрения внедрения / инверсии зависимостей потребитель никогда не должен знать или заботиться о том, какой тип реализует интерфейс .
Если вы расширяете logi c, о котором просите, что, если бы у вас было это?
public class First : IThing
{
public First(Dependency dep) : { }
}
public class Second : IThing
{
public Second(Dependency dep, OtherDependency other) : { }
}
А затем вы зарегистрировались ...
var builder = new ContainerBuilder();
// We can resolve OtherDependency from the container
builder.RegisterType<OtherDependency>();
// The two things we'd pick from
builder.RegisterType<First>().As<IThing>();
builder.RegisterType<Second>().As<IThing>();
var container = builder.Build();
// OtherDependency can come from the container
// but you're providing the Dependency as a parameter
var thing = container.Resolve<IThing>(new TypedParameter(typeof(Dependency), new Dependency());
В этом примере .. .. какой тип thing
? Это First
, потому что единственный параметр - Dependency
? Или это Second
из-за стандартного "последнего в победе" и потому, что OtherDependency
может поступать из контейнера?
Если это First
, то ... какой толк от контейнера для внедрения зависимостей вообще, поскольку вы фактически "новичок" в конкретном типе c на основе параметров конструктора, которые вам все равно нужно знать?
Если это Second
, то ... вы не получаете то, о чем вы просите, где вы каким-то образом получаете «вещь, соответствующую параметрам конструктора».
Я понимаю, что приведенное выше не дает вам ответа , но я надеюсь, что он получит в место, где вы можете понять, почему, возможно, то, что вы просите, не является тем, что Autofa c (или любой другой контейнер DI) может предоставить - у вас небольшая проблема с дизайном.
Ваш вопрос касается в одном из Autofa c FAQs интересно, как «выбрать реализацию по контексту».
Я предполагаю, что где-то в этой строке у вас есть параметр (или что-то еще) и на основе этого вам нужно «выбрать» другой тип модели представления.
FAQ, на который я ссылался, объясняет, почему это проблема дизайна, и предлагает несколько способов ее решения. Я не буду здесь повторять все, но вкратце:
- Вы можете перепроектировать / изменить интерфейсы, чтобы они не были идентичными. Если они не могут быть обработаны как идентичные, они не идентичны, даже если кажется, что у них одинаковые методы.
- Вы можете обновить способ регистрации вещей, которые потребляют ваши различные вещи. поэтому они в некоторой степени жестко запрограммированы, чтобы принимать тот тип, который они ожидают. Это сложная вещь, включающая
ResolvedParameters
и лямбда-регистрации, и на этой странице часто задаваемых вопросов есть рабочий пример, объясняющий это. - Вы можете использовать службы с ключами, чтобы присвоить каждому компоненту поставщика идентификатор, а затем использовать эти ключи / ID в атрибутах или во время операций ручного разрешения, чтобы указать то, что вы хотите.
- Вы можете использовать метаданные, чтобы прикрепить идентификатор поставщика или какой-либо другой идентификатор к регистрации каждого поставщика, чтобы «выбрать» нужный компонент резервного копирования во время выполнения .
Ознакомьтесь с FAQ для объяснений и примеров в коде. Здесь дается более глубокое объяснение того, как эти параметры будут работать.