Поле ввода Guice в классе, не созданном Guice

У меня есть такой класс, который я создаю где-то в своем коде:

class StarryEyes {
   @Inject MyValidator validator;

   public StarryEyes(String name) {
      //..
   }

   public doSomething() {
      // validator is NULL
   }
}

Я хочу, чтобы Guice внедрил экземпляр валидатора, который имеет аннотацию @Singleton. У меня есть модуль, который загружается при запуске, и он содержит строку:

bind(MyValidator.class);

Однако, он, кажется, не работает, так как «валидатор» всегда равен нулю. Я пробовал несколько вариантов, например:

bind(MyValidator.class)toInstance(new MyValidator());

или другие подобные вещи. Разве это не то, как должен работать Guice?

11
задан Robert Harvey 19 October 2010 в 04:13
поделиться

1 ответ

Обычно Guice нужно создавать объекты для их внедрения. Если вы просто вызовете new StarryEyes (name) , Guice никогда не увидит этот объект, поэтому не сможет его внедрить. Вы можете вызвать injector.injectMembers (obj) для объекта после того, как вы его создали. Я бы не рекомендовал это, так как вам следует избегать ссылки на инжектор в своем коде.

Что вам действительно нужно, так это Assisted Inject .С помощью Assisted Inject вы бы объявили конструктор для своего класса примерно так:

@Inject public StarryEyes(MyValidator validator, @Assisted String name)

Это означает, что валидатор - это параметр, который Guice должен ввести, а name должен быть «с помощью» (то есть предоставляется во время создания экземпляра).

Затем вы создаете такой интерфейс:

public interface StarryEyesFactory {
  StarryEyes create(String name);
}

С помощью Assisted Inject Guice может реализовать эту фабрику за вас. Вы привязываете его следующим образом:

bind(StarryEyesFactory.class).toProvider(
    FactoryProvider.newFactory(StarryEyesFactory.class, StarryEyes.class));

Затем вы вводите StarryEyesFactory везде, где хотите создать его экземпляр. Если раньше вы вызывали new StarryEyes (name) , то теперь вместо этого вы вызываете starryEyesFactory.create (name) . Когда вы вызываете create (name) на фабрике, он принимает имя, передает его конструктору и предоставляет сам привязанный валидатор.

Начиная с Guice 3 , вы делаете это с помощью FactoryModuleBuilder :

install(new FactoryModuleBuilder().build(StarryEyesFactory.class));
35
ответ дан 3 December 2019 в 02:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: