I spent some time wondering if it is possible to write a guice module which itself is parametrized with type T and uses its type parameter to specify bindings.
Like in this (not working) example:
interface A<T> {}
class AImpl<T> implements A<T>{}
interface B<T> {}
class BImpl<T> implements B<T> {}
class MyModule<T> extends AbstractModule {
@Override
protected vo开发者_开发百科id configure() {
bind(new TypeLiteral<A<T>>(){}).to(new TypeLiteral<AImpl<T>>(){});
bind(new TypeLiteral<B<T>>(){}).to(new TypeLiteral<BImpl<T>>(){});
}
}
I tried different approaches passing trying to pass T to MyModule as instance of Class/TypeLiteral but none of them worked. Help appreciated.
Regards, Łukasz Osipiuk
For that you will have to build each TypeLiteral from scratch, using com.google.inject.util.Types
. You could do something like that:
class MyModule<T> extends AbstractModule {
public MyModule(TypeLiteral<T> type) {
_type = type;
}
@Override protected void configure() {
TypeLiteral<A<T>> a = newGenericType(A.class);
TypeLiteral<AImpl<T>> aimpl = newGenericType(AImpl.class);
bind(a).to(aimpl);
TypeLiteral<B<T>> b = newGenericType(B.class);
TypeLiteral<BImpl<T>> bimpl = newGenericType(BImpl.class);
bind(b).to(bimpl);
}
@SuppressWarnings("unchecked")
private <V> TypeLiteral<V> newGenericType(Class<?> base) {
Type newType = Types.newParameterizedType(base, _type.getType());
return (TypeLiteral<V>) TypeLiteral.get(newType);
}
final private TypeLiteral<T> _type;
}
Please note that the private method newGenericType() will perform no control on types, it is your responsibility, in configure()
, to make sure that generic types can be correctly built with that method.
精彩评论