Reputation: 10419
I am using constructor DI with Google Guice.
public class MyClass {
private MyOtherClass otherclass
@Inject
MyClass(MyOtherClass otherClass) {
this.otherClass = otherClass
}
}
to get an instance of MyClass, I do:
com.google.inject.Injector.getInstance(MyClass.class)
All good. However, now I have two different versions of MyOtherClass. So I, need something like:
public class MyClass {
MyInterface myInterface
@Inject
MyClass(MyInterface myOtherInterface) {
this.myOtherInterface = myOtherInterface;
}
}
}
I need to be able at runtime, instantiate a
MyClass
with either a MyOtherClassA
or MyOtherClassB
instance.
So in one code path I need something like:
com.google.inject.Injector.getInstance(MyClass.class, MyOtherClassA) // A myClass sinstance which points to MyOtherClassA
and in another code path, I need:
com.google.inject.Injector.getInstance(MyClass.class, MyOtherClassB) // A myClass sinstance which points to MyOtherClassB
How do I do this?
Upvotes: 0
Views: 798
Reputation: 1138
There are two ways to achieve that
- Binding Annotations
Create the following Annotations class
public class Annotations {
@BindingAnnotation
@Target({FIELD, PARAMETER, METHOD})
@Retention(RUNTIME)
public @interface ClassA {}
@BindingAnnotation
@Target({FIELD, PARAMETER, METHOD})
@Retention(RUNTIME)
public @interface ClassB {}
}
Add the bindings in your module class
bind(MyInterface.class).annotatedWith(ClassA.class).toInstance(new MyOtherClassA());
bind(MyInterface.class).annotatedWith(ClassB.class).toInstance(new MyOtherClassB());
To get the necessary instance use this
injector.getInstance(Key.get(MyInterface.class, ClassA.class))
injector.getInstance(Key.get(MyInterface.class, ClassB.class))
MyClass constructor will look like this
@Inject
MyClass(@ClassA MyInterface myOtherInterface) {
this.myOtherInterface = myOtherInterface;
}
- @Named
Use the following bindings
bind(MyInterface.class).annotatedWith(Names.named("MyOtherClassA")).toInstance(new MyOtherClassA());
bind(MyInterface.class).annotatedWith(Names.named("MyOtherClassB")).toInstance(new MyOtherClassB());
To get the instance use this
injector.getInstance(Key.get(MyInterface.class, Names.named("MyOtherClassA")))
injector.getInstance(Key.get(MyInterface.class, Names.named("MyOtherClassB")))
MyClass constructor will look like this
@Inject
MyClass(@Named("MyOtherClassA") MyInterface myOtherInterface) {
this.myOtherInterface = myOtherInterface;
}
Please, refer to Guice documentation for more details.
Upvotes: 2