2011-01-25 7 views
26

Muszę powiązać jedną klasę jako implementację dwóch interfejsów. I powinien być powiązany w pojedynczym zakresie.Jak powiązać jedną implementację z kilkoma interfejsami za pomocą Google Guice?

Co robiłem:

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

Ale, oczywiście, prowadzi do powstania dwóch różnych sytuacjach, ponieważ są binded do poszczególnych klawiszy.

Moje pytanie brzmi: jak mogę to zrobić?

Odpowiedz

50

Wiki Guice ma a documentation about this use case.

Zasadniczo, to co należy zrobić:

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

Nie ma potrzeby, aby określić dodatkowe zajęcia: po prostu myśleć w kategoriach Provider s, a raczej odpowiedź przychodzi naturalnie.

+1

Najbardziej eleganckie rozwiązanie! –

2

Więc DefaultSettings to implementacja zarówno FirstSettings i SecondSettings, tj:

public class DefaultSettings implements FirstSettings, SecondSettings 
{ 
} 

Powiedzmy, że masz klasę EngineA i EngineB

public class EngineA 
{ 
    @Inject 
    private FirstSettings settings; 
} 

public class EngineB 
{ 
    @Inject 
    private SecondSettings settings; 
} 

i chcesz wprowadzić takie same realizacja.

Można zadeklarować interfejs DefaultSettingsInterface

public interface DefaultSettingsInterface extends FirstSettings, SecondSettings 
{ 
} 

i uczynić DefaultSettings wdrożyć DefaultSettingsInterface

public class DefaultSettings implements DefaultSettingsInterface 
{ 
} 

Wtedy konfiguracja może być:

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

Dzięki, Boris! Wierzę, że Twoje rozwiązanie działa! Właśnie znalazłem inny sposób samodzielnie: bind (FirstSettings.class). do (DefaultSettings.class). w (Singleton.class); bind (SecondSettings.class). do (FirstSettings.class). w (Singleton.class); Wygląda na to, że działa. Co myślisz? – Pavel

+1

Nie mogłem wiedzieć, że FirstSettings rozszerza SecondSettings. W takim przypadku jest on ważny i znacznie krótszy. Napisz rozwiązanie jako odpowiedź i po pewnym czasie wypromuj je jako najlepsze :) –

+0

Tak, to prawda. Moja wina, nie wspomniałem o tym :) – Pavel

3

Rozwiązanie, Znalazłem jest:

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

Działa w moim przypadku, ponieważ SecondSettings rozszerza FirstSettings.

+1

Działa tylko wtedy, gdy SecondSettings jest podklasą, podinterfejsem FirstSettings. Istnieją rozwiązania dla tego przypadku i inne, w których nie istnieje łącze między FirstSettings i SecondSettings. –

Powiązane problemy