Guice Beginner - Как связать конкретные классы? - PullRequest
38 голосов
/ 13 декабря 2011

У меня есть этот класс:

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

Где Door, Window и Roof - конкретные классы. Теперь, если я хочу реализовать Модуль для этого сценария, я бы сделал это так:

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

Но мне интересно, является ли это правильным способом связывания конкретных классов или есть более простые способы. Я чувствую, что есть более легкий путь к этому.

EDIT

Только что попробовал, и, похоже, это не работает:

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

РЕДАКТИРОВАТЬ 2

Кажется, что связывание вообще не нужно:

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

Также похоже на работу.

Ответы [ 3 ]

45 голосов
/ 13 декабря 2011

Это путь:

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

Поскольку это конкретные классы, как говорит Гисе, их нельзя привязать к себе: -)

Проверьте Binder документов, он отмечает:

bind(ServiceImpl.class);

Это утверждение по сути ничего не делает; он «привязывает класс ServiceImpl к себе» и не меняет поведение Guice по умолчанию. Вы все еще можете использовать это, если предпочитаете, чтобы ваш класс Module служил явным манифестом для предоставляемых им сервисов. Кроме того, в редких случаях Guice может быть не в состоянии проверить привязку во время создания инжектора, если это не указано явно.

Конкретные классы с конструктором, помеченным как @Inject, автоматически доступны для инъекции. Но это помогает разработчику (вам) знать, что настроено в модуле.

29 голосов
/ 13 декабря 2011

Guice's Just-In-Time связывание делает именно то, что вы хотите. Учитывая, что ваши Door, Window и Roof соответствуют следующим требованиям (цитируется в документации Guice ):

открытый конструктор без аргументов или конструктор с аннотацией @Inject

пустой реализации Модуля будет достаточно:

public class HouseModule extends AbstractModule {
    @Override
    protected void configure() {
    }
}
7 голосов
/ 13 декабря 2011

Связывание необходимо для связи интерфейса и класса реализации (например, для перехода к другой реализации в тестовой среде). Но поскольку у вас есть конкретные классы, вам не нужно связывать с , просто связывайте классы

...