Зарегистрировать компонент в Autofa c можно только одним способом. Последняя регистрация выигрывает. Вот почему, когда вы пытаетесь зарегистрироваться дважды, это не работает.
В общем, то, что вы пытаетесь сделать, не совсем совместимо с DI. Я действительно хочу, чтобы на вашем объекте был один конструктор и все. Кроме того, один из предложенных вами конструкторов имеет примитивный тип (int
), что также не очень хорошо для DI.
Если DI допускает два конструктора ... как он выбирает? Допустим, в контексте разрешения доступны оба параметра , параметр int
и , параметр DeviceListModel
. Какой конструктор является правильным?
Если вы используете int
в конструкторе ... поскольку вы действительно можете зарегистрировать только одну регистрацию данного System.Type
, это означает, что любой ваш объект принимает int
получит то же значение int
. Это верно?
Итак, все, что сказано, допустим, вы все еще действительно хотите, чтобы это произошло Вам нужно написать несколько собственных логик c.
Часть этого логика c должна знать, откуда вы ожидаете получить параметры конструктора. Это те вещи, которые вы решаете, которые должны быть уже зарегистрированы в контейнере? Или это то, что вы собираетесь передать?
То есть у вас есть два основных c сценария ios:
# All the stuff the DMPVM needs is _registered_
var b = new ContainerBuilder();
b.Register(3).As<int>();
b.RegisterType<DeviceListModel>().AsSelf();
b.RegisterType<DeviceMasterPageViewModel>().AsSelf();
var c = b.Build();
var d = c.Resolve<DeviceMasterPageViewModel>();
ИЛИ
# You plan on _passing in_ the values
var b = new ContainerBuilder();
b.RegisterType<DeviceMasterPageViewModel>().AsSelf();
var c = b.Build();
var d = c.Resolve<DeviceMasterPageViewModel>(new TypedParameter(typeof(int), 3));
(Это суть вопроса, который задают в комментариях. Знание этого важно для типа пользовательских логов c, которые вы напишите.)
Если вы предполагаете, что все вещи будут зарегистрированы тогда, скорее всего, вам нужно будет написать свой IConstructorSelector
. Autofa c поставляется с двумя - один, который соответствует наиболее доступным параметрам , и тот, который соответствует специфическая c сигнатура конструктора . Затем вы можете предоставить свой селектор конструктора во время регистрации.
Как именно написать, что вам решать. Я не думаю, что это хорошая идея, и в ней будет много предостережений, например, что произойдет, если у вас будет действительно долгая жизнь для разрешения компонента; и что это может сделать, чтобы app perf; и так далее. Это полностью зависит от вас.
Если вы передаете параметры, это немного проще. Вместо того чтобы писать селектор конструктора, вы можете зарегистрировать лямбду. Ищите параметры и используйте их по мере необходимости. Это задокументировано.
Это может выглядеть так:
b.Register((ctx, plist) => {
var intParam = plist
.OfType<TypedParameter>()
.Where(p => p.Type == typeof(int))
.FirstOrDefault();
if(intParam != null) {
return new DeviceMasterPageViewModel((int)intParam.Value);
}
// int param isn't found, do a similar search for the
// DeviceListModel parameter.
}).As<DeviceMasterPageViewModel>();
Как вы можете видеть, вы можете сделать некоторые динамические c фабричные логики c вправо там, основываясь на переданных параметрах.
Но, опять же, ваша жизнь будет намного проще, если вы полностью избежите этого.