Внедрение объектов с помощью Guice 3.0

Я только начал использовать Guice, и у меня возникли проблемы с пониманием способа инъекции guice. Я очень хорошо знаком с Spring, но это кажется немного другим.

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

public class SomeDAO {
    @NotNull
    private DB db = null;

    public SomeDAO (String databaseName) throws Exception{
        xxxxxxxxxxxxxxxxxxxxxxxx
    }
}

У меня есть контроллер, скажем:

public class SomeController {
    private SomeDAO someDAO;
}

Как мне использовать guice здесь, чтобы внедрить какой-нибудь объект DAO? Обратите внимание, что имя базы данных в конструкторе SomeDAO должно быть предоставлено из SomeController.

Спасибо.


person popcoder    schedule 03.07.2013    source источник


Ответы (1)


В идеале SomeController не нужно знать имя базы данных. Это будет происходить из файла конфигурации или из контекста вашего приложения, и вы должны внедрить свой DAO следующим образом:

public class SomeController {
  private final SomeDAO someDAO;

  @Inject 
  SomeController(SomeDAO someDAO) {
    this.someDAO = someDAO;
  }
}

А затем, чтобы ввести имя базы данных, вы можете сделать что-то вроде этого:

public class SomeDAO {

  @NotNull
  private DB db = null;

  @Inject
  public SomeDAO (@IndicatesDatabaseName String databaseName) throws Exception {
    ...
  }
} 

В этом случае Guice предоставит databaseName (см. https://code.google.com/p/google-guice/wiki/BindingAnnotations). Если вы хотите сообщить контроллеру имя базы данных, вы можете просто обновить DAO из контроллера (но все же внедрить контроллер) или использовать вспомогательную инъекцию.

ИЗМЕНИТЬ:

Если контроллеру действительно нужно знать о базе данных, вы можете использовать вспомогательную инъекцию:

public class SomeController {

  private final SomeDAO someDAO;

  @Inject
  SomeController(@Assisted String databaseName) {
    this.someDAO = new SomeDAO(databaseName);
  }
}
public interface ControllerFactory {
  public SomeController create(String databaseName);
}
public static class MyModule extends AbstractModule {
  @Override
  protected void configure() {
    install(new FactoryModuleBuilder()
    .implement(SomeController.class, SomeController.class)
    .build(ControllerFactory.class));
  }
}

А потом впрыснуть ControllerFactory туда, где нужно SomeController. Вы можете применить ту же вспомогательную инъекцию к SomeDAO, если в конечном итоге потребуется больше внедренных зависимостей.

person condit    schedule 03.07.2013
comment
Спасибо... но есть несколько баз данных для подключения, так что знания только с контроллерами... поэтому имя базы данных нужно передать на уровень DAO... Вы имеете в виду, что мне просто нужно создать новый SomeDAO (база данных )? В таком случае, это не шаблон DI, верно? Не могли бы вы показать мне, как это сделать с помощью DI с помощью Guice? - person popcoder; 04.07.2013
comment
Как ваш DAO подключается к нескольким БД? У них у всех одинаковая схема? Добавлен пример использования вспомогательной инъекции. Не обязательно плохо использовать new в мире DI - это просто зависит от вашей конкретной ситуации. Если только контроллеру когда-либо понадобится знать о DAO, а DAO не имеет других зависимостей, тогда придерживайтесь new. Если другие клиенты собираются создать экземпляр контроллера, вы также можете использовать вспомогательную инъекцию для этого. - person condit; 04.07.2013
comment
Я использую MongoDB, не сильно беспокоюсь о схеме в этом приложении. - person popcoder; 04.07.2013