Модуль Guice с параметрами типа - PullRequest
9 голосов
/ 12 сентября 2011

Я потратил некоторое время на размышления о том, можно ли написать модуль guice, который сам параметризован с типом T и использует его параметр типа для указания привязок.

Как в этом (не работающем) примере:

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 void configure() { 
        bind(new TypeLiteral<A<T>>(){}).to(new TypeLiteral<AImpl<T>>(){});
        bind(new TypeLiteral<B<T>>(){}).to(new TypeLiteral<BImpl<T>>(){}); 
    } 
} 

Я пробовал разные подходы, передавая T в MyModule как экземпляр Class / TypeLiteral, но ни один из них не работал.Помощь приветствуется.

С уважением, Лукаш Осипюк

1 Ответ

12 голосов
/ 12 сентября 2011

Для этого вам нужно будет собрать каждый TypeLiteral с нуля, используя com.google.inject.util.Types.Вы можете сделать что-то вроде этого:

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;
}

Обратите внимание, что закрытый метод newGenericType () не будет управлять типами, в configure() вы обязаны убедиться, что универсальные типы могут бытьправильно построен с помощью этого метода.

...