Как мне настроить один экземпляр компонента, предоставляющий несколько сервисов в Castle.Windsor?

Я хотел бы настроить контейнер Windsor так, чтобы один экземпляр в стиле singleton мог предоставлять две или более служб через контейнер.

Я обнаружил, что использование одного и того же типа в нескольких объявлениях компонентов (конфигурация на основе XML) приведет к созданию экземпляра этого типа для обеспечения интерфейса службы каждого компонента, что не является желаемым поведением.

Например:

interface IA { }
interface IB { }
class AB : IA, IB { ... } 

Я хочу, чтобы один экземпляр AB предоставлял услуги как IA, так и IB.

Конкретная причина, по которой я хочу это сделать, заключается в том, что моя конкретная реализация DAO расширяет несколько интерфейсов. С другой стороны, у меня есть несколько рабочих компонентов, которые содержат ссылки на разные интерфейсы. Конкретный экземпляр DAO уважает это, но конструкторы этих отдельных рабочих компонентов хотят реализовать свои отдельные интерфейсы, и я хочу, чтобы Castle.Windsor передавал один и тот же экземпляр объекта этим рабочим контейнерам через соответствующие служебные запросы.

лол, я думаю, это было ясно как грязь! :П

Кто-нибудь понимает, что я имею в виду, и есть ли у кого-нибудь идеи, как я могу добиться этого с помощью конфигурации XML для компонентов?


person Ash    schedule 26.03.2009    source источник


Ответы (4)


Вы проверили ответ на этот вопрос (особенно ссылка на сообщение на форуме), который кажется именно тем, что вы ищете. В некоторых примерах используется жизненный цикл Transient, но я думаю, что он также будет работать с Singleton.

Основная выгода от сообщения на форуме:

container.Register(Component.For<IEntityIndexController, ISnippetController>()
.ImplementedBy<SnippetController>()
.LifeStyle.Transient); 

Решение использует свободный интерфейс (и недавнюю сборку ствола), и в последний раз, когда я видел, было невозможно настроить в xml. Однако это возможно с помощью средства.

Удачи!

person Steven Lyons    schedule 26.03.2009

Вы пробовали использовать метод Forward:

container.Register(Component.For<IEntityIndexController>()
.ImplementedBy<SnippetController>()
.Forward (typeof(ISnippetController))
.LifeStyle.Transient);

Из моих экспериментов и из документации:

зарегистрировать типы сервисов от имени этого компонента

Я думаю, это должно помочь.

person Igor Brejc    schedule 15.07.2009
comment
Есть ли способ сделать это из XML конфигурации? - person Ash; 16.07.2009

Вы можете зарегистрировать экземпляр объекта (вместо реализации), который будет отвечать за различные реализации:

  var ab = new AB();
  container.Register( Component.For<IA>().Instance( ab) );
  container.Register( Component.For<IB>().Instance( ab) );

Я считаю, что это должно сработать. Однако по очевидным причинам для этого требуется конфигурация кода.

person jishi    schedule 26.03.2009
comment
Основная проблема заключается в использовании оператора new, что означает, что вы не используете автоматическое подключение для AB. - person Igor Brejc; 15.07.2009
comment
Последняя строка должна иметь вид container.Register( Component.For<IB>().Instance( ab).Named("IBImplementation") );, иначе вы получите ComponentRegistrationException: компонент AB не может быть зарегистрирован. Компонент с таким именем уже существует. - person Lu55; 21.07.2017

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

Classes.FromThisAssembly().Where(t => t.FullName == "Namespace.Classname").WithServiceAllInterfaces()

Кажется, это помогает мне.

person Todd A. Stedel    schedule 05.06.2014