2009-08-03 15 views
11

pueden obtener 2 casos únicos del mismo tipo subyacente?Obtención de múltiples embarazos únicos Guice del mismo tipo

Obviamente, esto es trivial en la primavera, ya que se basa en las instancias con nombre al que se adjunta un alcance pero no puede ver el equivalente en guice que es sobre los tipos de unión a clases de implementación. Tenga en cuenta que no quiero tener que enlazar a la instancia ya que las instancias en cuestión son inyectadas con otras dependencias por guice.

Respuesta

15

Es fácil de Guice también! Cree dos anotaciones de presagiar, decir @One y @Two y luego

bind(MySingleton.class).annotatedWith(One.class).toInstance(new MySingleton()); 
bind(MySingleton.class).annotatedWith(Two.class).toInstance(new MySingleton()); 

y luego

@Inject 
public SomethingThatDependsOnSingletons(@One MySingleton s1, 
    @Two MySingleton t2) { ... } 
+0

o un método @Provides si tiene dependencias, me he perdido este bit de los documentos (http://code.google.com/docreader/#p=google-guice&s=google-guice&t=ProvidesMethods) dependencias pueden pasarlo como parámetros del método. El inyector ejercerá los enlaces para cada uno de estos antes de invocar el método. – Matt

+0

No es necesario que lo vincule a una instancia. Dos anotaciones diferentes para la misma clase, en el alcance singleton, ya crearán dos instancias separadas. –

+2

@Filip, intenté con lo que sugería y recibí la misma instancia para ambas anotaciones. Usé 'bind (MySingleton.class) .annotatedWith (One.class) .to (MySingleton.class) .in (Singleton.class); bind (MySingleton.class) .annotatedWith (Two.class) .to (MySingleton.class) .in (Singleton.class); ' –

13

me gustaría complementar la respuesta de Marcin, añadiendo que no tiene por qué limitarse a la utilización de toInstance() o métodos del proveedor en tal situación.

El siguiente funcionará igual de bien:

bind(Person.class).annotatedWith(Driver.class).to(MartyMcFly.class).in(Singleton.class); 
bind(Person.class).annotatedWith(Inventor.class).to(DocBrown.class).in(Singleton.class); 

[...]

@Inject 
public BackToTheFuture(@Driver Person marty, @Inventor Person doc) { ... } 

Guice inyectará las dependencias como de costumbre cuando una instancia de las clases de Marty McFly y DocBrown.


Tenga en cuenta que también funciona cuando se quiere enlazar varios conjuntos unitarios de la mismo tipo:

bind(Person.class).annotatedWith(Driver.class).to(Person.class).in(Singleton.class); 
bind(Person.class).annotatedWith(Inventor.class).to(Person.class).in(Singleton.class); 

Para que esto funcione, debe asegurarse de que Person no está ligada en el Singleton alcance, explícitamente en el módulo de Guice, o con la anotación @Singleton. Más detalles en this Gist.

Edit: El código de ejemplo que doy como ejemplo proviene de un Guice Grapher Test. Ver las pruebas de Guice es una excelente manera de comprender mejor cómo usar la API (que también se aplica a cada proyecto con buenas pruebas de unidades).

+1

Me encanta el ejemplo –

+0

Gracias Jesse :) El código de muestra que utilicé para ilustrar mi punto en realidad proviene de una prueba para la extensión de Guice Grapher. Pensé que era gracioso y lo pegué como está. Debería haber puesto un enlace a la fuente, sin embargo (lo haré en este momento). Como comentario adicional, me encanta tu blog y especialmente tus artículos prácticos sobre Guice/Google Collections (http://publicobject.com/). Necesitamos más blogs como el tuyo. Entonces, gracias por esto, también. –

+0

@eneveu, sugiere que su solución sea una alternativa a la de Marcin. Me parece que el caso de uso que describes es diferente al suyo, porque el tuyo supone que hay dos clases diferentes de implementación del controlador (MartyMcFly, DocBrown), en oposición a dos instancias de una clase concreta (Driver). Cuando trato de usar esta técnica en el último caso, obtengo dos referencias al mismo singleton usando esto: 'bind (MySingleton.class) .annotatedWith (One.class) .to (MySingleton.class) .in (Singleton.class); bind (MySingleton.class) .annotatedWith (Two.class) .to (MySingleton.class) .in (Singleton.class); ' –

Cuestiones relacionadas