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

у меня такой класс, что я создаю себя где-то в своем коде:

class StarryEyes {
   @Inject MyValidator validator;

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

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

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

bind(MyValidator.class);

однако, похоже, он не работает, поскольку "валидатор" всегда равен null. Я пробовал несколько вариантов, таких как:

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

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

1 ответов


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

вы реально наверно хотите здесь Помощь Впрыснуть. С помощью Assisted Inject вы объявите конструктор для своего класс что-то вроде этого:

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

что validator - это параметр, который Guice должны впрыснуть, а name должно быть "assisted" (то есть предоставлено во время создания экземпляра).

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

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

С помогать впрысните, 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));