2011-01-25 15 views
26

Necesito vincular una clase como implementación de dos interfaces. Y debe estar vinculado en un alcance único.¿Cómo vincular una implementación a algunas interfaces con Google Guice?

lo que he hecho:

bind(FirstSettings.class). 
    to(DefaultSettings.class). 
    in(Singleton.class); 
bind(SecondSettings.class). 
    to(DefaultSettings.class). 
    in(Singleton.class); 

Pero, obviamente, que conduce a la creación de dos instancias diferentes, debido a que están encuadernados a las diferentes teclas.

Mi pregunta es ¿cómo puedo hacer eso?

Respuesta

50

La wiki de Guice tiene a documentation about this use case.

Básicamente, esto es lo que debe hacer:

// Declare that the provider of DefaultSettings is a singleton 
bind(DefaultSettings.class).in(Singleton.class); 

// Bind the providers of the interfaces FirstSettings and SecondSettings 
// to the provider of DefaultSettings (which is a singleton as defined above) 
bind(FirstSettings.class).to(DefaultSettings.class); 
bind(SecondSettings.class).to(DefaultSettings.class); 

No hay necesidad de especificar las clases adicionales: basta pensar en términos de Provider s y la respuesta viene en lugar de forma natural.

+1

¡La solución más elegante! –

2

Así, DefaultSettings es una aplicación tanto del FirstSettings y SecondSettings, es decir:

public class DefaultSettings implements FirstSettings, SecondSettings 
{ 
} 

Digamos que usted tiene una clase EngineA y EngineB

public class EngineA 
{ 
    @Inject 
    private FirstSettings settings; 
} 

public class EngineB 
{ 
    @Inject 
    private SecondSettings settings; 
} 

y que le gustaría para inyectar la misma implementación.

Se puede declarar una interfaz DefaultSettingsInterface

public interface DefaultSettingsInterface extends FirstSettings, SecondSettings 
{ 
} 

y hacer que el implemento DefaultSettingsDefaultSettingsInterface

public class DefaultSettings implements DefaultSettingsInterface 
{ 
} 

A continuación, la configuración puede ser:

bind(FirstSettings.class).to(DefaultSettingsInterface.class); 
bind(SecondSettings.class).to(DefaultSettingInterface.class); 
bind(DefaultSettingsInterface.class).to(DefaultSettings.class).in(Singleton.class); 
+1

Gracias, Boris! ¡Creo que su solución funciona! Acabo de encontrar otra forma por mí mismo: bind (FirstSettings.class). a (DefaultSettings.class). en (Singleton.class); bind (SecondSettings.class). a (FirstSettings.class). en (Singleton.class); Parece que también funciona. ¿Qué opinas? – Pavel

+1

No podía saber que FirstSettings extiende SecondSettings. En ese caso, es válido y mucho más corto. Publique su solución como respuesta y después de un tiempo la promocione como la mejor :) –

+0

Sí, es cierto. Mi error, no lo mencioné :) – Pavel

3

La solución, que he encontrado es:

bind(FirstSettings.class). 
    to(DefaultSettings.class). 
    in(Singleton.class); 
bind(SecondSettings.class). 
    to(FirstSettings.class). 
    in(Singleton.class); 

Funciona en mi caso, porque SecondSettings extiende FirstSettings.

+1

Funciona solo si SecondSettings es una subclase, una subinterfaz de FirstSettings. Existen soluciones para este caso y otras donde no existe un enlace entre FirstSettings y SecondSettings. –

Cuestiones relacionadas