2011-12-13 10 views
33

que tienen esta clase:Guice Beginner - ¿Cómo enlazar clases concretas?

public class House { 
    private final Door door; 
    private final Window window; 
    private final Roof roof; 

    @Inject 
    public House(Door door, Window window, Roof roof) { 
     this.door = door; 
     this.window = window; 
     this.roof = roof; 
    } 
} 

Dónde Door, WindowRoof y son clases concretas. Ahora si quiero implementar un módulo para este escenario, lo haría así:

public class HouseModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(Door.class).to(Door.class); 
     bind(Window.class).to(Window.class); 
     bind(Roof.class).to(Roof.class); 
    } 
} 

pero me pregunto si este es el camino correcto para unir clases concretas, o si hay maneras más fáciles. Siento que hay una manera más fácil de esto.

EDITAR

acaba de intentar esto, y no parece funcionar:

1) Binding points to itself. 
    at de.tarent.guice.ex._1.HouseModule.configure(HouseModule.java:10) 

EDIT 2

Parece que hay unión se necesita en absoluto:

Injector injector = Guice.createInjector(); 
House house = injector.getInstance(House.class); 

También parece funcionar.

Respuesta

22

Just-In-Time binding de Guice hace exactamente lo que desea.Teniendo en cuenta sus Door, WindowRoof y cumplen los requisitos siguientes (citados de la Guice documentation):

ya sea un bien público, sin argumentos constructor, o un constructor con la anotación @Inject

un módulo vacío la implementación será suficiente:

public class HouseModule extends AbstractModule { 
    @Override 
    protected void configure() { 
    } 
} 
+0

¿A dónde va el módulo vacío? ¿Cómo sabe Guice relacionarlos? – djechlin

+0

@djechlin Esto dependerá de cómo esté configurada su aplicación. Por ejemplo, una aplicación basada en [Play] (https://www.lightbend.com/play-framework) esperará que dicho archivo de módulo esté en el paquete raíz, o configurable mediante 'play.modules.enabled' en la aplicación .conf – Siddhartha

40

Este es el camino a seguir:

protected void configure() { 
    bind(Door.class); 
    bind(Window.class); 
    bind(Roof.class); 
} 

Puesto que son clases concretas, como dice Guice, no se puede ellas se unen a los mismos :-)

Mira la Binder docs, se notas:

bind(ServiceImpl.class); 

Esta declaración hace prácticamente nada; "ata la clase ServiceImpl a sí mismo" y no cambia el comportamiento predeterminado de Guice. Es posible que desee utilizar esto si prefiere que su clase Module sirva como un manifiesto explícito para los servicios que brinda. Además, en casos excepcionales, es posible que Guice no pueda validar un enlace en el momento de la creación del inyector, a menos que se indique explícitamente.

Las clases de hormigón con el constructor marcado como @Inject están disponibles automáticamente para inyección. Pero ayuda al desarrollador (usted) a saber qué está configurado en el módulo.

+0

Realmente confundido: ¿significa que "automáticamente disponible en módulos" significa para todos los módulos de su proyecto globalmente? ¿O conoce el módulo local del paquete o coincide con los nombres de los módulos o algo por el estilo? – djechlin

+0

Simplemente significa que ni siquiera debería tener que indicar cómo hacer la encuadernación ya que la puerta, la ventana y el techo son clases concretas. Están disponibles en todos los módulos. Si tienes implementaciones diferentes de una interfaz determinada, ENTONCES tienes que ayudar a Guice. – Jalayn

+0

No necesita un módulo cuando no necesita vincular una interfaz a una clase. – Noya

6

La vinculación es necesaria para vincular la clase de interfaz e implementación (para cambiar a otra implementación en el entorno de prueba, por ejemplo). Pero ya que tiene clases concretas, no es necesario vincular a, solo enlace las clases

Cuestiones relacionadas