Как сделать необязательную привязку в Guice? - PullRequest
3 голосов
/ 24 июня 2010

Вот мой клиент:

class Client {
    @Inject(optional=true) Service service;
}

Иногда эта служба не нужна, и мы знаем эту информацию при запуске JVM (т.е. до запуска связывателя).Как сделать привязку необязательной?Если я вообще не указываю привязку, она пытается создать новую Службу (и терпит неудачу, потому что нет конструктора с нулевым аргументом: " Ошибка при внедрении в package.Client.service (Service.java:40): МожетЯ не могу найти подходящий конструктор в package.Service."), и я не могу сделать:

binder.bind(Service.class).toInstance(null);

, потому что Guice, кажется, запрещает нули.Есть идеи?

Ответы [ 3 ]

7 голосов
/ 24 июня 2010

Вы используете Guice 2.0? Я пробовал это как с Service как интерфейс (поле службы всегда null), так и с классом (null, если он не может создать новый экземпляр с привязкой JIT, экземпляр, если Можно). И то, и другое похоже на то, что вы ожидаете.

Ни в одном из случаев я не использовал привязку типа bind(Service.class).toInstance(null). Если вы сделаете это, то вам нужно убедиться, что все точки впрыска для Service указывают, что они позволяют ему быть null. Это можно сделать, пометив точку впрыска любой аннотацией под названием @Nullable (вы можете сделать свою собственную или использовать существующую):

class Client {
    @Inject @Nullable Service service;
}
3 голосов
/ 04 сентября 2010

Если вы хотите сделать существование привязки необязательным, вы можете использовать @Inject(optional = true) для инъекций полей и методов.Для инжекторов типа contructor и других параметров необходимо использовать вспомогательный класс, например:

class Foo {
  public String hello(Helper helper) {
    return Helper.string;
  }
  private static final class Helper {
    @Inject(optional = true) public String string = "";
  }
}

Обратите внимание, что приведенное выше не позволяет вводить null, поэтому Foo # hello никогда не вернет null.Если вы хотите разрешить null, просто добавьте аннотацию @Nullable.Имейте в виду, что код, подобный следующему, не будет работать, если вы не предоставили привязку (к нулю, если ничего больше) для строки:

class Bar {
  @Inject @Nullable public String hello(@Nullable String string) {
    return string;
  }
}
2 голосов
/ 25 июня 2010

Я не мог воспроизвести это поведение.Когда я запускаю этот пример кода, инжектор создает, и необязательное внедрение остается неудовлетворенным.Программа печатает null:

public class OptionalInjections {

  static class Service {
    public Service(Void v) {} // not injectable
  }

  static class Client {
    @Inject(optional = true) Service service;
  }

  public static void main(String[] args) {
    Injector i = Guice.createInjector();
    Client client = i.getInstance(Client.class);
    System.out.println(client.service);
  }
}

Не могли бы вы воспроизвести это в тестовом примере JUnit и отправить его в Отслеживание проблем Guice ?

...