如何编写通用的FactoryModuleBuilder?

时间:2012-05-10 16:02:12

标签: generics types dependency-injection guice

我想知道如何表示以下绑定的通用版本,该版本不会因xxx cannot be used as a key it is not fully specified

而失败
install(new FactoryModuleBuilder().
   implement(new TypeLiteral<SomeClass<T,?>>(){}, 
      new TypeLiteral<SomeOtherClass<T, U>>(){}).
   build(SomeFactory.class);

似乎implement方法不适用于参数化类型参数。

3 个答案:

答案 0 :(得分:2)

由于Guice使用类型文字参数的方式,这是不可能的。 TypeLiterals需要具体类型,正如您从异常中看到的那样,它不能接受通用参数。

引用@ jesse-wilson

  

请注意,Guice不允许对非类型的绑定进行绑定   完全合格。例如,您可以绑定Map<String, Integer>但是   你无法绑定Map<K, V>。   https://stackoverflow.com/a/1117878/654187

您可以“完全限定”这些绑定,如下所述: https://stackoverflow.com/a/1120990/654187

但我怀疑这是你想要的。

好消息是你仍然可以在没有辅助注射的情况下编写这个工厂:

public class SomeFactory{
    @Inject
    private SomeDependency someDependency;

    public <T> SomeClass<T, ?> buildSomeClass(T t){
        return new SomeOtherClass<T, Object>(t, someDependency);
    }
}

答案 1 :(得分:1)

AlenVrečkoposted

  

Imho你可以用泛型做的最好就像

     

install(new Assist2<Payment, RealPayment>(PaymentFactory.class){});

     

install(new Assist3<SomeClass<Foo, Bar>, SomeOtherClass<Foo, Bar>, SomeFactory<Foo>(){});

     

应该很容易实现这种方法。只要看看   TypeLiteral的来源。

     

如果你绝对需要输入类似参数:

     

install(new CustomAssist<Baz>(){});其中

     

CustomAssist<T> extends Assist<SomeClass<Foo,T>,SomeOtherClass<Foo,Bar>{...

     

可能是可能的,但不是微不足道的。但是很有趣。

答案 2 :(得分:0)

从@johncarl

继续

如果您只是注入someDependency,那么您将在创建工厂时获取实例。为了使它像FactoryModuleBuilder构造的工厂一样工作,你需要注入Injector

public class SomeFactory{
    @Inject
    private Injector injector;

    public <T> SomeClass<T, ?> buildSomeClass(T t) {
        return new SomeOtherClass<T, Object>(t, injector.getInstance(SomeDependency));
    }
}