2011-01-25 2 views
26

Ho bisogno di associare una classe come implementazione di due interfacce. E dovrebbe essere legato in un ambito singleton.Come associare un'implementazione a poche interfacce con Google Guice?

quello che ho fatto:

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

Ma, ovviamente, porta alla creazione di due istanze diverse, perché sono binded alle diverse chiavi.

La mia domanda è come posso farlo?

risposta

50

La wiki di Guice ha a documentation about this use case.

Fondamentalmente, questo è ciò che si dovrebbe fare:

// 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); 

Non v'è alcuna necessità di specificare eventuali classi aggiuntive: basta pensare in termini di Provider s e la risposta viene piuttosto naturale.

+1

La soluzione più elegante! –

2

Quindi, DefaultSettings è un'implementazione sia del FirstSettings e SecondSettings, vale a dire:

public class DefaultSettings implements FirstSettings, SecondSettings 
{ 
} 

Diciamo che avere una classe EngineA e EngineB

public class EngineA 
{ 
    @Inject 
    private FirstSettings settings; 
} 

public class EngineB 
{ 
    @Inject 
    private SecondSettings settings; 
} 

e volete conferire il medesimo implementazione.

È possibile dichiarare un'interfaccia DefaultSettingsInterface

public interface DefaultSettingsInterface extends FirstSettings, SecondSettings 
{ 
} 

e rendere il DefaultSettings attrezzo DefaultSettingsInterface

public class DefaultSettings implements DefaultSettingsInterface 
{ 
} 

Poi la configurazione può essere:

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

Grazie, Boris! Credo che la tua soluzione funzioni! Ho appena trovato un altro modo da solo: bind (FirstSettings.class). a (DefaultSettings.class). in (Singleton.class); bind (SecondSettings.class). a (FirstSettings.class). in (Singleton.class); Sembra che funzioni anche. Cosa ne pensi? – Pavel

+1

Non potevo sapere che FirstSettings estende SecondSettings. In tal caso è valido e molto più breve. Pubblica la tua soluzione come risposta e dopo un po 'di tempo promuoverla come la migliore :) –

+0

Sì, è vero. Colpa mia, non l'ho detto :) – Pavel

3

La soluzione, ho trovato è:

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

Funziona nel mio caso, perché SecondSettings estende FirstSettings.

+1

Funziona solo se SecondSettings è una sottoclasse, subinterface di FirstSettings. Esistono soluzioni per questo caso e altre in cui non esiste alcun collegamento tra FirstSettings e SecondSettings. –