Suppose I have an interface Foo. It is implemented by concrete implementations CompositeFoo, FooA, FooB, and FooC. Moreover, CompositeFoo is as follows:
public class CompositeFoo implements Foo {
@Inject public CompositeFoo(List<? extends Foo> elements);
}
I wish to, in a Guice PrivateModule, bind Foo to a CompositeFoo with the list being a FooA followed by something that is either a FooB or a FooC. (This must be a list, as order matters; this rules out multibindings as a solution.)
The problem is that I am seeing some circularity involved. Suppose the provider of the CompositeFoo is as follows:
public class CompositeFooProvider implements Provider<Foo> {
@Inject private FooA first;
@Inject @Named("Inner") private Foo second;
@Override public Foo get() { return new CompositeFoo(asList(first, second)); }
}
The module providing the second Foo (either FooB or FooC) is as follows:
public class InnerModule extends PrivateModule {
private final Key<? super Foo> bindingKey; // key will be exposed, bound to the Foo below
// configure() deals with deps of FooB and FooC
@Provides
public Foo getInnerFoo(...) {
// Assume that the args are such that if they are "valid", we should return a FooB, else FooC
if (...) return new FooB(...);
else return new FooC(...);
}
}
The circularity arises when I try to construct the outer module: I need to install the InnerModule (passing in Key.get(Foo.class, Names.named("Inner")) as the binding key) in order to get the second Foo, but Foo is already bound in the outer module due to its binding to the CompositeFooProvider. How do I resolve this circularity? Will converting the @Provides method to its own Provider suffice?
The
@Provides Foomethod is providing a binding forFoowhich conflicts with theFoobinding in the outer module. So bind it as something else:Or perhaps you can just do
directly and not bother passing in the binding key.