#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.