I am new to Guice DI. And I would like to get my scenario clarified.
To put it simple, Is there any replacement of MapBinder through Guice @annotations?
My Scenario:
Interface A{}
Class A1 implements A{}
Class A2 implements A{}
I would like to Inject the implementation class of A as follows,
if(param = One) then Inject A1 to A
if(param = Two) then Inject A2 to A
I understand that the above could be done with MapBinder, but I would like to do it through annotations as follows,
Class A1 implements A
{
@Inject(param = One)
A1(){}
}
Class A2 implements A
{
@Inject(param = Two)
A2(){}
}
So making the class annotated with params could automatically picks and inject the class based on the parameter (One or Two).
Since @Inject cannot accept params, overriding @Inject would help in this scenario? if so, how do we do so?
Or Is this scenario could only be achieved through binding using MapBinder (The reason why I wouldn't want to use binder is that we would want to define the binding map of key value pair explicitly, but using annotations just simply annotate the implementation class with params - easier maintenance).
Thanks in advance.
To answer your follow-up questino, I believe what you are looking for are named injects. See this example:
public class GuiceNamedTest extends AbstractModule {
public static void main(String[] args) {
Injector i = Guice.createInjector(new GuiceNamedTest());
i.getInstance(InstaceOne.class);
i.getInstance(InstaceTwo.class);
}
@Override
protected void configure() {
Bean beanOne = new Bean();
beanOne.name = "beanOne";
Bean beanTwo = new Bean();
beanTwo.name = "beanTwo";
bind(Bean.class).annotatedWith(Names.named("one")).toInstance(beanOne);
bind(Bean.class).annotatedWith(Names.named("two")).toInstance(beanTwo);
bind(InstaceOne.class);
bind(InstaceTwo.class);
}
public static class Bean {
String name;
}
public static interface A {}
public static class InstaceOne implements A {
@javax.inject.Inject
public InstaceOne(@Named("one") Bean b1) {
System.out.println(b1.name);
}
}
public static class InstaceTwo implements A {
@javax.inject.Inject
public InstaceTwo(@Named("two") Bean b1) {
System.out.println(b1.name);
}
}
}
Here, I am using annotatedWith
to name my guice-handled instances. One of them corresponds to the String "one" and the other to "two", analogue to your example.
I can then, in my implementations of A
have specific injections of these beans using the @Named
annotation.
The result when running above code is:
beanOne
beanTwo
As you can see, it injected the correct instance of my bean into the right implementation.
Hope that helps,
Artur