Поддерживает ли Castle-Windsor ForwardedTypes через конфигурацию XML - PullRequest
9 голосов
/ 08 ноября 2008

У меня есть класс, который реализует несколько интерфейсов. Я хотел бы зарегистрировать эти интерфейсы через XML. Все, что я нашел, это документация для нового интерфейса Fluent. Эта опция поддерживается через XML? Что будет задействовано в добавлении этой функции?

1 Ответ

10 голосов
/ 08 ноября 2008

[ Обновление ] Это теперь возможно в Виндзоре 2.1 или новее. Смотрите документацию по синтаксису здесь .


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

Итак, сначала мы добавляем средство, которое будет определять, когда для типа создается обработчик, и в то же время регистрирует любые перенаправленные службы, чтобы они указывали на существующий обработчик:

public class HandlerForwardingFacility : AbstractFacility
{
  IConversionManager conversionManager;

  protected override void Init()
  {
    conversionManager = (IConversionManager)Kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);
    Kernel.HandlerRegistered += new HandlerDelegate(Kernel_HandlerRegistered);      
  }

  void Kernel_HandlerRegistered(IHandler handler, ref bool stateChanged)
  {
    if (handler is ForwardingHandler) return;

    var model = handler.ComponentModel;

    if (model.Configuration == null) return;

    var forward = model.Configuration.Children["forward"];
    if (forward == null) return;

    foreach (var service in forward.Children)
    {
      Type forwardedType = (Type)conversionManager.PerformConversion(service, typeof (Type));
      Kernel.RegisterHandlerForwarding(forwardedType, model.Name);
    }
  }
}

И затем, конечно, нам нужно использовать это в коде, для этого примера у меня будет мутантный компонент утка / собака, который поддерживает два отдельных сервиса - IDuck и IDog:

public interface IDog
{
  void Bark();
}

public interface IDuck
{
  void Quack();
}

public class Mutant : IDog, IDuck
{
  public void Bark()
  {
    Console.WriteLine("Bark");
  }

  public void Quack()
  {
    Console.WriteLine("Quack");
  }
}

Теперь для фактической настройки контейнера:

 <castle>
  <facilities>
    <facility id="facility.handlerForwarding" type="Example.Facilities.HandlerForwardingFacility, Example" />
  </facilities>
  <components>
    <component id="mutant" service="Example.IDog, Example" type="Example.Mutant, Example">
      <forward>
        <service>Example.IDuck, Example</service>
      </forward>
    </component>
  </components>
</castle>

И теперь мы можем с радостью выполнить такой тест:

  WindsorContainer container = new WindsorContainer(new XmlInterpreter());

  var dog = container.Resolve<IDog>();
  var duck = container.Resolve<IDuck>();

  Assert.AreSame(dog, duck);

Надеюсь, это поможет.

...