Guice провайдер, который предоставляет один и тот же тип в разных областях - циклическая зависимость - PullRequest
0 голосов
/ 25 апреля 2020

Я бы хотел @RequestScope класса (например, Rabbit.class). Простой способ сделать это - аннотировать класс с помощью @RequestScope или добавить инструкцию в модуль

  public void configure(){
    bind(Rabbit.class).in(RequestScope.class)
    ...
  }

Однако это немного опасное изменение, поэтому я бы хотел Защитите это поведение с помощью флага эксперимента. Флаг эксперимента может быть разным (true или false) для любого данного запроса. Поэтому RequestScope'ing должен выполняться провайдером, который внедряет флаг.

public class RabbitProvider extends Provider<Rabbit> {

    @Inject
    RabbitProvider(boolean flag, @ThisIsRequestScoped Rabbit requestScopedRabbit, @ThisIsNotRequestScoped Rabbit newRabbit) {
      // save to instance vars
    }

    @Override
    Rabbit get() {
      return flag ? requestScopedAnimal : newAnimal;
    }
}
  public void configure(){
    bind(Rabbit.class).annotatedWith(ThisIsRequestScoped.class).in(RequestScoped.class);
    bind(Rabbit.class).annotatedWith(ThisIsNotRequestScoped.class);
    bind(Rabbit.class).toProvider(RabbitProvider.class);
  }

Не хорошо. Круговая зависимость:

Rabbit -> RabbitProvider -> @ThisIsRequestScoped Rabbit -> Rabbit

Оба ключа @ThisIsNotRequestScoped Rabbit и @ThisIsRequestScoped Rabbit указывают на кролика, который указывает на кролика , Не уверен, как исправить этот круг. Любые идеи? Можно ли даже связать тип с провайдером, который предоставит этот тип в разных областях?

1 Ответ

0 голосов
/ 26 апреля 2020

Ах - нашел способ, который работает, если у вас есть тип суперкласса.

Предположим, что Rabbit расширяет Animal, затем: пусть весь код приложения вводит Animal, связывает Animal с провайдером, и вы можете дать Rabbit любые привязки как аннотированная привязка @ThisIsRequestScoped. В провайдере, поскольку Rabbit неявно привязан к самому себе, вы можете внедрить его (будет создан новый экземпляр, или вы можете ввести @ThisIsRequestScoped Rabbit, чтобы получить запрос, находящийся в области действия).

...