2011-12-13 13 views
33

mam tej klasy:Guice Beginner - jak wiązać konkretne klasy?

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; 
    } 
} 

Gdzie Door, Window i Roof konkretne zajęcia. Teraz, jeśli chcę, aby wdrożyć moduł do tego scenariusza, zrobiłbym to tak:

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

Ale zastanawiam się, czy jest to właściwy sposób powiązać konkretne zajęcia, lub jeśli istnieją prostsze sposoby. Czuję, że jest łatwiejszy sposób na to.

EDIT

Właśnie próbowałem, i nie wydaje się działać:

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

Edytowanie 2

Wydaje się, że nie jest wiążąca w ogóle potrzebne:

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

Wydaje się również działać.

Odpowiedz

22

Guice za Just-In-Time binding robi dokładnie to, co chcesz.Biorąc pod uwagę twoje Door, WindowRoof i spełniają następujące wymagania (cytat z Guice documentation):

zarówno publiczne, nie-argumenty konstruktora lub konstruktor z dopiskiem @Inject

pusty moduł implementacja będzie wystarczająca:

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

Gdzie jest pusty moduł? Jak Guice wie, jak je odnieść? – djechlin

+0

@dłamlin To zależy od konfiguracji Twojej aplikacji. Na przykład aplikacja oparta na [Play] (https://www.lightbend.com/play-framework) będzie oczekiwać, że taki plik modułu znajdzie się w pakiecie głównym lub będzie można go konfigurować za pomocą 'play.modules.enabled' w aplikacji .conf – Siddhartha

40

To jest do zrobienia:

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

Ponieważ są one konkretne zajęcia, jak mówi Guice, nie można związać je do siebie :-)

Sprawdź Binder dokumenty, to Uwagi:

bind(ServiceImpl.class); 

To stwierdzenie ma w zasadzie nic; "wiąże klasę ServiceImpl" i nie zmienia domyślnego zachowania Guice. Możesz nadal używać tego, jeśli wolisz, aby twoja klasa Module służyła jako wyraźny manifest dla usług, które zapewnia. Ponadto w rzadkich przypadkach Guice może nie być w stanie zweryfikować wiązania w czasie tworzenia wtryskiwacza, chyba że zostanie to wyraźnie podane.

Klasy betonowe z konstruktorem oznaczonym @Inject są automatycznie dostępne do wtrysku. Pomaga jednak deweloperowi (ty) wiedzieć, co jest skonfigurowane w module.

+0

Naprawdę zagmatwany - czy "automatycznie dostępne w modułach" oznacza dla wszystkich modułów w projekcie na całym świecie? Czy jest on świadomy modułu lokalnego dla pakietu lub czy pasuje do nazw modułów? – djechlin

+0

To po prostu oznacza, że ​​nie powinieneś nawet wskazywać sposobu wiązania, ponieważ drzwi, okno i dach są konkretnymi klasami. Są one dostępne we wszystkich modułach. Jeśli masz różne implementacje danego interfejsu, TO musisz pomóc Guice. – Jalayn

+0

Nie potrzebujesz modułu, gdy nie ma potrzeby wiązania interfejsu z klasą. – Noya

6

Powiązanie jest potrzebne do połączenia interfejsu i klasy implementacji (na przykład do zmiany implementacji w środowisku testowym). Ale ponieważ masz konkretne klasy, nie ma potrzeby wiązania do, wystarczy powiązać klasy