Guice: вспомогательные инъекции и поставщики
Предположим, у меня есть класс следующим образом:
public class ComplicatedImpl implements Complicated {
@Inject
public ComplicatedImpl(Integer normal, @Assisted String assisted);
public void addListener(Listener listener);
}
Теперь у меня есть ComplicatedFactory
вот так:
public interface ComplicatedFactory {
public Complicated build(String assisted);
}
Можно ли при использовании FactoryModuleBuilder
связать ComplicatedFactory
такой, что когда build()
вызывается, мы делаем эквивалент
ComplicatedImpl impl = new ComplicatedImpl(normal, assisted);
impl.addListener(listener);
return impl;
в отличие от обычного случая возвращения нового ComplicatedImpl
напрямую?
Я пытался связать ComplicatedImpl
в какой-то форме Provider
, но кажется, что я буду ходить по кругу с этим...
1 ответ
Я не верю, что это возможно в Guice; FactoryModuleBuilder может делать очень мало, кроме как смешивать явные аргументы конструктора с зависимостями. К счастью, написание ручной фабрики относительно просто:
public class ListeningComplicatedFactory {
@Inject Provider<Integer> normalProvider;
public Complicated createComplicated(String assisted, Listener listener) {
ComplicatedImpl impl = new ComplicatedImpl(normalProvider.get(), assisted);
// If ComplicatedImpl uses member injection, inject an Injector and call
// injector.injectMembers(impl) to call @Inject-annotated methods/fields.
impl.addListener(listener);
return impl;
}
}
Если вы готовы поставить addListener
на Complicated
Интерфейс, у вас также есть возможность написать оболочку, которая внедряет ComplicatedFactory, создает новые экземпляры и вызывает addListener
на них сразу. Это может быть особенно эффективно, если вы связываете ComplicatedFactory в PrivateModule, а затем открываете только свой новый ComplicatedWrapperFactory, делая ваш ComplicatedWrapperFactory единственным способом создания новых сложных реализаций.