2010-08-20 8 views
6

Digamos que tiene un componente como estoCastillo de Windsor - cómo resolver los componentes en base a parámetros del constructor

public class MyComponent 
{ 
    public MyComponent(string name) 
    { 
    } 
} 

que básicamente quiere tener los parámetros del constructor proporcionados comporte como parte del identificador de componente cuando resolverlo. Si nunca lo resolvió con ese conjunto de parámetros, creará una nueva instancia.

En otras palabras, quiero modificar de alguna manera el siguiente test para tener éxito:

IWindsorContainer container = new WindsorContainer(); 
container.Register(Component.For<MyComponent>()); 
MyComponent a1 = container.Resolve<MyComponent>(new { name = "a" }); 
MyComponent a2 = container.Resolve<MyComponent>(new { name = "a" }); 
MyComponent b = container.Resolve<MyComponent>(new { name = "b" }); 

Assert.AreSame(a1, a2); 
Assert.AreNotSame(a1, b); 

Actualmente se produce un error porque va a crear una instancia con nombre = a, entonces devolver el mismo objeto para todos futuro nombre = ay nombre = b.

Gracias!

+1

¿Estás ** seguro ** que quieres hacer esto en tiempo de resolución en lugar de tiempo de registro? –

Respuesta

6

Normalmente esto se hace en el momento del registro, no en el tiempo de resolución. De hecho, llamar a Resolve() en su código debería ser raro ya que está usando el contenedor como un localizador de servicios.

container.Register(
    Component.For<MyComponent>() 
      .Named("comp_a") 
      .DependsOn(new { name = "a" }), 
    Component.For<MyComponent>() 
      .Named("comp_b") 
      .DependsOn(new { name = "b" })); 

var a1 = container.Resolve<MyComponent>("comp_a"); 
var a2 = container.Resolve<MyComponent>("comp_a"); 
var b = container.Resolve<MyComponent>("comp_b"); 
Assert.AreSame(a1, a2); 
Assert.AreNotSame(a1, b); 

En lugar de utilizar Resolve() como en mi código (que es puramente para fines de prueba) que normalmente utiliza reemplazos de servicio o un selector para seleccionar qué controlador myComponent para inyectar en sus otros servicios.

+0

Soy consciente de que puedo hacerlo, pero en realidad estoy usando la instalación de auto factoría. De forma predeterminada, puede seleccionar componentes con los métodos Get {component-name}, pero para mí tiene que ser dinámico. Sin embargo, parece que es posible escribir un selector que me permita implementar un método Get (nombre-componente) o algo similar. – Cameron

+0

@Cameron: recomiendo crear otra pregunta que indique todos los detalles relevantes sobre su problema y un caso de prueba relevante. No hubo mención de la instalación de la fábrica mecanografiada hasta este comentario. –

+0

Literalmente quería saber si lo que describí en la pregunta original era posible. Sé lo que hace la instalación de soporte de fábrica al contenedor que se encuentra debajo, ya que he leído el código fuente, así que solo quería saber si el contenedor en sí admitía algo similar a lo que describí. Si no es así, está bien, y lo implementaré de otra manera. – Cameron

Cuestiones relacionadas