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));