Регистрация и разрешение разных конструкторов параметров с разным TypeOf в Autofac - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть класс с 2 конструкторами с 2 различными типизированными параметрами в конструкторах, это работает хорошо, пока у меня не будет единственного конструктора, но как только я создаю другой конструктор и пытаюсь его разрешить, autofa c вылетает и говорит Укажите конструктор, используя конфигурацию конструктора, я попытался зарегистрировать конструктор в DI, но первая регистрация переопределяет вторую

builder.RegisterType<DeviceMasterPageViewModel>().UsingConstructor(typeof(DeviceListModel));
builder.RegisterType<DeviceMasterPageViewModel>().UsingConstructor(typeof(int));

вот мой класс с 2-мя конструкторами

public DeviceMasterPageViewModel(DeviceListModel scannendDevice)
    {}
 public DeviceMasterPageViewModel(int selectedDeviceID)
    {}

я не являюсь в состоянии понять, как мне зарегистрировать этот класс в DI, чтобы при передаче параметра типа c указанный конструктор typeof получал имя

1 Ответ

1 голос
/ 10 апреля 2020

Зарегистрировать компонент в 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 вправо там, основываясь на переданных параметрах.

Но, опять же, ваша жизнь будет намного проще, если вы полностью избежите этого.

...