I have the following class wherein I need method injection using Guice.
@Singleton
public class A {
private final Injector injector;
@Inject
public A(Injector injector) {
this.injector = injector;
}
public void method1() {
...
final XInterface x = this.injector.getInstance(Key.get(XInterface.class, Names.named("provideX")));
...
}
}
And the module contains the following provides method:
public class MyModule extends AbstractModule {
@Override void configure() {
// no binding and scope for class A
}
@Provides
@Named("provideX")
public XInterface provide(@Named("isTest") boolean isTest, X x, XMock xMock) {
return isTest ? xMock : x;
}
}
Where isTest has a provider in the same module and can be ignored for this discussion.
Now, this injection in class A gives me the following error:
Unable to create binding for `A`. It was already configured on one or more child injectors or private modules. If it was in a PrivateModule, did you forget to expose the binding?
and the rest of the stacktrace isn't very helpful.
After digging around for a while and trying out a few things, I found that just defining a Singleton scope for class A in the MyModule.configure() like so : bind(A.class).in(Singleton.class); and removing the existing @Singleton annotation on the class A solved the error. Now my question is two fold:
- What caused the error in my first implementation?
- What is the difference between defining a singleton scope in the module and annotating a class with singleton scope and why did that solve the problem?
Thanks in advance!