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

#castle-windsor #typed-factory-facility

#castle-windsor #объект typed-factory

Вопрос:

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

 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»)

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

Ответ №1:

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

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

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

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

Комментарии:

1. да, это действительно кажется не лучшим поведением. Пожалуйста, зарегистрируйте запрос в системе отслеживания проблем Windsor.