2012-04-18 2 views
2

Это работает:Guice, инъекционное TypeLiteral <T> при использовании @AssistedInject

public static class SomeGenericType<T> { 
    private TypeLiteral<T> type; 

    @Inject 
    public SomeGenericType(TypeLiteral<T> type) { 
     this.type = type; 
    } 

    public Class<? super T> getType() { 
     return type.getRawType(); 
    } 
} 

Guice автоматически впрыскивает TypeLiteral, представляющий строку, когда я делаю:

@Inject SomeGenericType<String> foo; 

Но при попытке то же самое с Assisted Inject:

public static interface FooFactory<T> { 
    Foo<T> create(String name); 
} 

public static class Foo<T> { 

    @AssistedInject 
    public Foo(TypeLiteral<T> type, @Assisted String name) { 
     .... 

Мой модуль выглядит следующим образом:

public static class TestMod extends AbstractModule { 
    @Override 
    protected void configure() { 
     install(new FactoryModuleBuilder().build(new TypeLiteral<FooFactory<String>>(){})); 
    } 
} 

я получаю исключение при установке модуля:

TypeLiteral<T> cannot be used as a Key, it is not fully specified. 

Это, конечно, TypeLiteral, что я пытаюсь Inject, что является проблемой, так как общий завод действительно работает хорошо, когда я удалить его ,

Итак, я, вероятно, просто покажу свою собственную фабрику, но мне любопытно, должно ли это работать? Это вопрос использования FactoryModuleBuilder несколько иначе?

ответ

4

Как вы обращаетесь к экземпляру FooFactory? Я построил вариацию на код ниже, и он работал на меня:

public class AnotherGuiceTest { 
    public static void main(String[] args) { 
     Injector i = Guice.createInjector(new TestMod()); 
     FooFactory<String> ff = i.getInstance(Key.get(new TypeLiteral<FooFactory<String>>() {})); 
     ff.create("myname"); 
    } 
} 

interface FooFactory<T> { 
    Foo<T> create(String name); 
} 

class Foo<T> { 

    @Inject 
    public Foo(TypeLiteral<T> type, @Assisted String name) { 
     System.out.println(type.getRawType()); 
     System.out.println(name); 
    } 
} 

class TestMod extends AbstractModule { 
    @Override 
    protected void configure() { 
     install(new FactoryModuleBuilder().build(new TypeLiteral<FooFactory<String>>() {})); 
    } 
} 

Выходы:

class java.lang.String 
myname 

Примечание Я использовал регулярные @Inject аннотацию, а не @AssistedInject, которые я думаю для нескольких конструкторов в завод. Это также работает, если вы впрыскивать экземпляр непосредственно:

public class AnotherGuiceTest { 
    public static void main(String[] args) { 
     Injector i = Guice.createInjector(new TestMod()); 
     AppClass ac = i.getInstance(AppClass.class); 
    } 
} 

class AppClass { 
    @Inject 
    public AppClass(FooFactory<String> fooFactory) { 
     fooFactory.create("test"); 
    } 
} 

Выходы:

class java.lang.String 
test 
+0

Aha .. поэтому это была проблема установки. Спасибо, что нашли время проверить и ответить. Оказывается, это связано с тем, что у меня была банка из GIN, guice-assistedinject-snapshot.jar вместо guice-assistedinject-3.0.jar (сторона примечания, обычный вспомогательный инъект, похоже, работает с этой банкой, а не с дженериками) – aidanok