Рассмотрите API, который вы создаете здесь, особенно в отношении будущих расширений или реализаций. Очевидно, у вас есть несколько экземпляров FirstDep с состоянием, потому что SecondDep зависит от конкретного FirstDep, но будущий SecondDep может не зависеть от того же FirstDep (или вообще от любого FirstDep). Тот факт, что createMyObject(first)
может быть сокращением для createMyObject(first, factory.createSecond(first))
, зависит от вашего бизнес-кейса, и я не думаю, что в Guice есть сокращение, позволяющее сделать такое предположение.
Тем не менее, у вас есть два варианта. Во-первых, вы можете создать очень маленький помощник:
// Encapsulate the createMyObject(first) shorthand.
class MyObjectHelper {
@Inject MyObjectFactory rawFactory;
MyObject createMyObject(FirstDep first) {
return rawFactory.createMyObject(first, rawFactory.createSecond(first));
}
}
Или, во-вторых, вы можете использовать @AssistedInject
< /a> чтобы Guice эффективно перегружал конструктор:
class MyObject {
// Multiple @AssistedInject constructors, selected based on which parameters
// are marked with @Assisted.
@AssistedInject public MyObject(@Assisted FirstDep first,
SecondFactory secondFactory, ThirdDep third) {
this(first, secondFactory.createSecond(first), third);
}
@AssistedInject public MyObject(@Assisted FirstDep first,
@Assisted SecondDep second, ThirdDep third) { /**/ }
}
interface SecondFactory {
// Note that @Assisted annotations are not needed here. Every parameter in
// these interfaces is for assisted injection, by definition.
SecondDep createSecond(FirstDep first);
}
interface MyObjectFactory {
MyObject createMyObject(FirstDep first);
MyObject createMyObject(FirstDep first, SecondDep second);
}
Хотя создание отдельной фабрики для каждого класса немного более многословно, я думаю, вы обнаружите, что это поможет сохранить ваши классы/фабрики отдельными и простыми в использовании, и это аккуратно избегает потенциальной циклической ссылки, которую я могу " не помните навскидку, поддерживает ли Guice. Я склонен выставлять свои фабрики как вложенные интерфейсы:
class SecondDep {
interface Factory {
SecondDep create(FirstDep first);
}
@Inject public SecondDep(@Assisted FirstDep first) { /**/ }
}
... который затем позволяет вам найти и обновить Second.Factory
точно рядом с классом, который он поддерживает.
person
Jeff Bowman
schedule
03.03.2014
MyObject createMyObject(@Assisted FirstDep first)
, который обертывает два сгенерированных метода, но это не сработает. Guice требует, чтобы фабричный тип был интерфейсом. - person Jorn   schedule 03.03.2014