2011-01-07 22 views
5

Supongamos que IFo ha sido implementado por Foo e IBar implementado por FirstBar y SecondBar.Castle Windsor: utilizando el registro de convenciones junto con implementaciones específicas

El uso de este registro de la convención:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface()) 

Tendremos tres entradas en el contenedor:

IFoo = Foo 
IBar = FirstBar 
IBar = SecondBar 

Ahora bien, ¿cómo podemos ajustamos este registro para ser capaz de decir que el recipiente para ¿Queremos que SecondBar se registre solo? Clase de:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface() 
     .For<IBar>().Select<SecondBar>()) 

Caso de uso: tenemos muchos servicios en nuestra aplicación, todos registrados por convenciones. Sin embargo, algunas de las interfaces de servicio tienen dos o más implementaciones (por ejemplo, implementación real, implementación falsa e implementación de prueba). El registro de convenciones los registrará a todos bajo la misma interfaz y, al resolver la interfaz, obtendremos la primera implementación (en orden no determinista). Queremos poder seleccionar una implementación específica para esos servicios durante el registro. ¿Cómo podemos hacer eso?

Respuesta

3

Esto es lo que hizo el trabajo realizado:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface()) 
     .ConfigureFor<IBar>(c => 
      c.If((k, m) => m.Implementation == typeof(SecondBar))); 

Esto registra efectivamente sólo impl SecondBar para el servicio IBar. De esta forma, si hay más de una implementación para un servicio determinado, podemos indicarle al escáner convencional cuál es el que queremos.

Seguimos adelante y creamos métodos poco agradable de extensión para este propósito:

public static BasedOnDescriptor Select<TService, TImpl>(this BasedOnDescriptor desc) 
{ 
    return desc.ConfigureFor<TService>(c => c.If((k, m) => m.Implementation == typeof(TImpl))); 
} 

public static BasedOnDescriptor Ignore<TService>(this BasedOnDescriptor desc) 
{ 
    return desc.ConfigureFor<TService>(c => c.If((k, m) => false)); 
} 

Ahora podemos utilizar de esta manera:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface()) 
     .Select<IBar, SecondBar>() 
     .Ignore<ISomeService>() 

Con todo esto funciona muy bien. Creo que esos dos métodos podrían estar en Castle.Windsor adecuada. @Krzysztof Koźmic: ¿dónde envío un parche? :)

+0

Github. Puede ser una buena idea mencionar esto en el grupo de usuarios de castillos en grupos de google primero para recopilar comentarios primero. Cheers –

+0

Sí, el Ignorar es exactamente lo que necesito – PandaWood

5

Ajuste su convención. Obviamente es amplio.

container.Register(
    AllTypes.FromThisAssembly() 
     .Where(t => t.Namespace != "Acme.Tests") 
     .WithService.DefaultInterface()) 
Cuestiones relacionadas