Должен ли типизированный объект фабрики генерировать исключение, когда я запрашиваю компонент по имени, который не зарегистрирован? - PullRequest
1 голос
/ 04 мая 2011

Если я регистрирую компонент в контейнере с именем (не беспокойтесь ... надуманный пример!)

container.Register(Component.For<double>().Instance(Math.PI).Named("pi")

И просите разрешить этот тип сервиса с другим именем

container.Resolve<double>("e")

Я получаю исключение ComponentNotFound.Но теперь, если я использую типизированное фабричное средство

interface IDoubleFactory { double GetDoubleByName(string name); }

container.Register(  
  Component.For<DoubleSelector, ITypedFactoryComponentSelector>()   
  Component.For<IDoubleFactory>().AsFactory(f => f.SelectedWith<DoubleSelector>())
  Component.For<double>().Instance(Math.PI).Named("pi"))

public class DoubleSelector : DefaultTypedFactoryComponentSelector
{
  protected override string GetComponentName(MethodInfo method, object[] arguments) 
  {
    return arguments[0] as string;
  }
}

и попытаюсь использовать фабрику для разрешения поддельного имени

container.Resolve (). GetDoubleByName ("e")

Я получаю пи вместо исключения.Похоже, что, дав имя ITypedFactoryComponentSelector, которое не помогло, оно вернулось к использованию Type (в данном случае double) и схватило первое, зарегистрированное против него.

1 Ответ

0 голосов
/ 04 мая 2011

Ответ может быть ошибкой в ​​Виндзоре 2.5.1. Контракт для ITypedFactoryComponentSelector предполагает, что если вы вернете нуль для ComponentType, но не ноль для ComponentName, поиск будет выполняться по имени, а не по типу. Но две проблемы встают у вас на пути, если вы попытаетесь это сделать.

Согласно источникам GitHub, код в DefaultTypedFactoryComponentSelector.BuildFactoryComponent вызывает GetCompatibleArrayItemType для того, что может быть нулевым указателем ComponentType, что вызывает исключение. Это похоже на ошибку, простую и понятную.

Если вы найдете способ обезопасить это, то, похоже, что метод TypedFactoryComponentResolver.Resolve не совсем устраивает правильные перегрузки ядра для разрешения в случаях, когда ComponentType равен нулю. Мне гораздо менее понятно, является ли это ошибкой или отсутствием в моем понимании того, какие методы IWindsorContainer.Resolve делают. Тем не менее, отправка различным методам (Resolve<object>(string key), например), кажется, делает свое дело.

Оба класса незапечатаны, так что это легко исправить с помощью производных классов.

...