Castillo de Windsor: ¿Cómo puedo actualizar un registro de componentes
-
06-09-2019 - |
Pregunta
Si he definido en la configuración:
container.Register(
Component.For<X.Y.Z.IActivityService>()
.ImplementedBy<X.Y.Z.ActivityService>()
.ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName }))
.LifeStyle.Transient
);
y deseo extender esta configuración y añadir un nuevo elemento a la propiedad oyentes matriz de modo que la configuración final es efectiva:
container.Register(
Component.For<X.Y.Z.IActivityService>()
.ImplementedBy<X.Y.Z.ActivityService>()
.ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName, "MyOtherListenerID" }))
.LifeStyle.Transient
);
he de conocer el contenido de la "matriz" cuando se registra por primera vez el componente, o puedo recuperar el registro de componentes y agregar a ella?
Deseo poner en práctica mis config utilizando el patrón decorador de tal manera que puedo construir mi contenedor, y luego extenderla según sea necesario para diferentes escenarios. Esto significa que tengo que ser capaz de acceder a los componentes ya configurados y añadir a ellos.
Fue pensando en tener un DefaultConfig
clase que devuelve la configuración por defecto y luego una de las clases más "DecoratedConfig
", que se extendería la configuración por defecto.
Así que tendría
IWindsorContaner c = new DecoratedConfig(new DefaultConfig()).InitialiseContainer();
DefaultConfig
establecería la ActivityService
con un DefaultActivityListener
(como se muestra en el ejemplo).
DecoratedConfig
reconocería que ActivityService
había sido creado y añadir su propia implementación de escucha a la matriz Listeners
en ActivityService
.
Gracias.
Solución
suscribirse al evento Kernel.ComponentModelCreated
. Puede cambiar cualquier parámetro de componente a partir de ahí. Ver este . No hace Tienes a ser una instalación que hace esto, pero es conveniente.
Otros consejos
@mausch, adusting la configuración ComponentModel
parece ser la solución.
La siguiente prueba hace effecitvely lo que necesito sin tener que conectar a la ComponentModelCreatedEvent
para que pueda realizar los cambios, incluso después de que se crea el modelo de componentes.
Voy a envolver la funcionalidad que un método de extensión, y tratar de adaptarse a una API fluida.
[TestMethod]
public void ArrayPropertyTestApi3()
{
using (Castle.Windsor.WindsorContainer container = new Castle.Windsor.WindsorContainer())
{
container.Register(Component.For<Components.A>().ServiceOverrides(ServiceOverride.ForKey("I").Eq(new[] { typeof(Components.B).FullName })));
container.Register(Component.For<Components.B>());
container.Register(Component.For<Components.C>());
IHandler h = container.Kernel.GetHandler(typeof(Components.A));
if (h != null)
{
var config = h.ComponentModel.Configuration;
if (config != null)
{
var items = config.Children.Single(c => c.Name == "parameters")
.Children.Single(c => c.Name == "I")
.Children.Single(c => c.Name == "list")
as MutableConfiguration;
items.Children.Add(new MutableConfiguration("item", string.Format("${{{0}}}", typeof(Components.C).FullName)));
}
}
Components.A svc = container.Resolve<Components.A>();
Assert.IsTrue(svc.I.Length == 2);
Assert.IsTrue(svc.I[0].Name == "B");
Assert.IsTrue(svc.I[1].Name == "C");
}
}
Es preferible utilizar el ComponentModel contribuyentes construcción con el IContributeComponentModelConstruction
interfaz, ya que es la forma recomendada de la configuración de los componentes más.
Para ello, deberá implementar la interfaz para especificar los cambios a aplicar a la configuración
public class ChangeConfiguration : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
// filter your model to match the subset you're interested in
// change the configuration for matching models
}
}
A continuación, antes de registrar sus componentes, que acaba de añadir la clase a su contenedor:
container.Kernel.ComponentModelBuilder.AddContributor(new ChangeConfiguration());
Todos los componentes A continuación, pasar a través de esta clase, donde puede cambiar su configuración. En su caso changeing la lista de detectores, etc (supongo que este es el nombre anterior de los interceptores)