Как я могу ввести свойство, только если значение не является нулевым во время выполнения с использованием Unity? - PullRequest
1 голос
/ 10 августа 2010

У меня есть интерфейс для разрешения, и у одной из зависимостей сопоставленного объекта есть свойство, которое я хотел бы установить со значением, которое доступно только при разрешении объекта верхнего уровня.

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

Возможно ли внедрение этого условного свойства?

Я пробовал это...

container.RegisterType<ProductInstanceValidatorBase, CartItemPurchaseTypeValidator>("CartItemPurchaseTypeValidator", new InjectionProperty("AccountEntity", null);

... но там сказано, что я не могу использовать нулевое значение!

Я также пробовал это в разрешении ...

container.Resolve<ProductInstanceValidatorBase>(new PropertyOverride("AccountEntity", value));

... но это вызывает исключение, когда значение равно нулю.Он говорит:

Вывод типа параметра не работает для нулевых значений.Укажите тип параметра в явном виде, используя правильно настроенный экземпляр классов InjectionParameter или InjectionParameter.Имя параметра: parameterValue

По сути, я собираюсь зарегистрировать свойство, которое устанавливается только с переопределением и только тогда, когда значение переопределения не равно нулю.Есть идеи?Конечно, с семантической точки зрения, внедрение свойства должно быть необязательным.

Cheers, Ian.

Ответы [ 3 ]

5 голосов
/ 10 августа 2010

Одним из возможных решений этой проблемы является реализация шаблона нулевого объекта и передача Account.Empty, если у вас нет действующей учетной записи.Вот как может выглядеть класс:

public class Account {
   public static readonly Account Empty = new Account();
}

//at resolution time
Account account = null;
if (HasAccount) 
  account = GetAccount();
else 
  account = Account.Empty;

container.Resolve<ProductInstanceValidatorBase>(new PropertyOverride("AccountEntity", account));

Таким образом, учетная запись никогда не будет null, и Entity Framework не будет жаловаться.

Однако я чувствую, что у вас может быть большийпроблема с дизайном системы.Контейнер IoC допускает более слабосвязанную систему, в которой проводка компонентов определяется до запуска программы, а не , пока выполняется.Судя по названию, AccountEnyity является классом сущности, а не классом обслуживания, и вы обычно не регистрируете сущности в контейнере IoC, только услуги.

В светеВыше я бы предположил, что AccountEntity должно быть не инъецируемым свойством, а нормальным свойством.Затем вы выводите создание ProductInstanceValidatorBase на завод и позволяете ему позаботиться о настройке свойства AccountEntity

public interface IProductInstanceValidatorFactory{
  ProductInstanceValidatorBase Create(Account account);
}
public class ProductInstanceValidatorFactory : IProductInstanceValidatorFactory{
  public ProductInstanceValidatorBase Create(Account account){
     var validator = new ProductInstanceValidator();
     validator.AccountEnity = account;
     return validator;
  }
}

. Вам даже не нужно регистрировать ProductInstanceValidatorBase в Unity, а вместо этого зарегистрировать завод,Вот так выглядит использование фабрики:

Account account = null;
container.Resolve<IProductInstanceValidatorFactory>().Create(account);
4 голосов
/ 29 октября 2010

Вы можете использовать InjectionParameter со значениями NULL, но вы должны указать тип.Для двух ваших сценариев я предполагаю, что ваш параметр AccountEntity имеет тип или является производным от IAccount:

container.RegisterType<ProductInstanceValidatorBase, CartItemPurchaseTypeValidator>("CartItemPurchaseTypeValidator", new InjectionProperty<IAccount>(null);

Обратите внимание, что я отбросил имя, поскольку оно не требуется специально в приведенном выше сценарии, но оно необходимосценарий ниже.

container.Resolve<ProductInstanceValidatorBase>(new PropertyOverride("AccountEntity", new InjectionProperty<IAccount>(null)));
0 голосов
/ 10 августа 2010

Я бы хотел согласиться с Игорем.Однако, если вам абсолютно необходимо разрешить Entity, почему бы просто не взять ваш контейнер IoC в качестве зависимости конструктора, а затем попытаться Resolve в конструкторе?

...