inversion-of-control - windsor - castle.net core
¿Castle-Windsor admite ForwardedTypes a través de la configuración XML? (1)
Tengo una clase que implementa múltiples interfaces. Me gustaría registrar estas interfaces a través de XML. Todo lo que encontré es documentación para la nueva interfaz fluida. ¿Esta opción es compatible a través de XML? ¿Qué implicaría agregar esta característica?
[ Actualizar ] Esto ahora es posible en Windsor 2.1 o posterior. Vea la documentación para la sintaxis aquí .
Esta característica no se ha implementado en el intérprete XML hasta el momento ... sin embargo, no es difícil agregar soporte a través de una instalación (obviamente, esta técnica también es útil cuando se desean agregar otras características ausentes del analizador de configuración existente).
Primero, agregamos una instalación que detectará cuándo se crea un controlador para un tipo y, al mismo tiempo, registrará cualquiera de los servicios reenviados para que apunten al controlador existente:
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);
}
}
}
Y luego, por supuesto, necesitamos hacer uso de esto en el código, para este ejemplo voy a tener un componente mutante de pato / perro que admite dos servicios separados: IDuck e 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");
}
}
Ahora para configurar realmente el contenedor:
<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>
Y ahora podemos felizmente ejecutar una prueba como esta:
WindsorContainer container = new WindsorContainer(new XmlInterpreter());
var dog = container.Resolve<IDog>();
var duck = container.Resolve<IDuck>();
Assert.AreSame(dog, duck);
Espero que esto ayude.