Внутри DLL мы определили два класса («Class1» и «Class2»), которые наследуются от интерфейса («IInterface») и базового класса («BaseClass»).
Мы используем свободный интерфейс регистрации Castle Windsor (http://using.castleproject.org/display/IoC/Fluent+Registration+API) для автоматической регистрации всех классов, унаследованных от «BaseClass» (внутри этой DLL), на их соответствующие интерфейсы.
Для конкретной персонализации мы использовали (с сегодняшнего дня) файл "castle.xml", который переопределяет (с помощью тегов "component") связи между интерфейсами и конкретными классами (зарегистрированными в API регистрации Fluent). Мы загружаем этот XML-файл в конструктор WindsorContainer.
Код выглядит примерно так:
//container's initialization:
var resource = new FileResource("Castle.xml");
var interpreter = new XmlInterpreter(resource);
var container = new WindsorContainer(interpreter);
container.AddFacility<TypedFactoryFacility>();
//...
//automatic type registration:
container.Register(
AllTypes
.FromAssemblyContaining<BaseClass>()
.BasedOn<BaseClass>()
.WithService.Select(
(t1, t2) => t1.GetInterfaces()
.Except(new[] {typeof (IDisposable)})
.Union(new[] {t1}))
.Configure(a => a.Named(a.ServiceType.Name)
.LifeStyle.Transient)
.AllowMultipleMatches()
);
По умолчанию, если мы запрашиваем у Касла объект IInterface, мы получаем «Class1»; чтобы получить «Class2», мы должны указать его внутри файла «Castle.xml».
Сегодня я попытался избавиться от файла castle.xml, указав директивы «Component» внутри текущей конфигурации (ДО Директивы «AllTypes»):
container.Register(
Component
.For<IInterface>()
.ImplementedBy<Class2>()
.LifeStyle.Transient);
... но мы все равно получаем объект Class1, как будто бы плавная директива «AllTypes» переопределяет директиву «Component» (и это странно, потому что директива «component» внутри xml-файла работает).
Что я делаю не так?
РЕДАКТИРОВАТЬ: я получил доступ к компоненту по имени ключа, ".Named ()" решил проблему (спасибо Кшиштофу):
container.Register(
Component
.For<IInterface>()
.ImplementedBy<Class2>()
.Named(typeof(IInterface).Name)
.LifeStyle.Transient);