Reputation: 7604
I have a set of 15-20 classes that depend on a class that implements generic interface with bound type parameters. The interface looks like this:
interface Handler<F extends Foo, T extends Foo> {
T handleFoo(String methodName, F myFoo);
}
And a single implementation of Handler that uses reflection to deal with all the specialised cases of Foo, because they're all "similar but different".
class ConcreteHandler<Foo, Foo> implements Handler<Foo, Foo> {
T handleFoo(String methodName, F foo) {
// do your thing
}
}
I'd like to be able to use this class in a type-safe way in its collaborators, like:
@Inject ACollaborator(Handler<Bar, Baz> barHandler) {...}
where Bar
and Baz
both extend Foo
. Unfortunately, Guice complains that Handler<Bar, Baz>
is not bound when I try this in my module:
bind(new TypeLiteral<Handler<? extends Foo, ? extends Foo>>() {}).to(ConcreteHandler.class);
I have also tried the following, which causes a compiler error because ConcreteHandler
is not a subclass of Handler<Bar, Baz>
:
bind(new TypeLiteral<Handler<Bar, Baz>>() {}).to(ConcreteHandler.class);
I have so many of these Collaborator objects that I am not keen on the thought of implementing Handler for each combination of types, and putting in 20 separate binding statements for them.
How do I accomplish what I'm attempting with Guice, that is binding a single concrete implementation to a single interface with different generic parameters?
Upvotes: 3
Views: 651
Reputation: 101
You can manage to do this by creating the TypeLiteral representing the binding target, probably with a raw type involved.
You'll see an example of how to do this in this question: Reconstructing generic types at runtime with Guice via Types and TypeLiterals
Basically what you'll needs is something to construct the Key of each Handler<> you want bound.
Then you can say something like:
bindHandler(Bar.class, Baz.class);
Which will:
TypeLiteral<ConcreteFoo<Bar, Baz>>
TypeLiteral<Foo<Bar, Baz>>
Also I think in your example ConcreteHandler should implement Handler[?]
Upvotes: 2