在Guice注入一家通用工厂

以下代码是在给定Foo生成Bar的工厂示例。 工厂不关心T是什么:对于任何类型T ,它可以从Foo创建Bar Foo

 import com.google.inject.*; import com.google.inject.assistedinject.*; class Foo { public void flip(T x) { System.out.println("flip: " + x); } } interface Bar { void flipflop(T x); } class BarImpl implements Bar { Foo foo; @Inject BarImpl(Foo foo) { this.foo = foo; } public void flipflop(T x) { foo.flip(x); System.out.println("flop: " + x); } } interface BarFactory {  Bar create(Foo f); } class Module extends AbstractModule { public void configure() { bind(BarFactory.class) .toProvider( FactoryProvider.newFactory( BarFactory.class, BarImpl.class ) ); } } public class GenericInject { public static void main(String[] args) { Injector injector = Guice.createInjector(new Module()); Foo foo = new Foo(); Bar bar = injector.getInstance(BarFactory.class).create(foo); bar.flipflop(0); } } 

当我运行代码时,我从Guice得到以下错误:

 1) No implementation for BarFactory was bound. at Module.configure(GenericInject.java:38) 2) Bar cannot be used as a key; It is not fully specified. 

我可以在Guice文档中找到generics的唯一参考说明使用TypeLiteral 。 但我没有文字类型,我有一个与工厂无关的通用占位符。 有小费吗?

一种选择是手工编写BarFactory样板:

 class BarImplFactory implements BarFactory { public  Bar create(Foo f) { return new BarImpl(f); } } 

绑定变成了

 bind(BarFactory.class).to(BarImplFactory.class); 

如果你认为guice是一个类似于spring的布线系统,那么连接一个通用实例并没有多大意义。 您将特定实例连接到键,以便当另一个实例化类使用@Inject BarFactory标记某些内容时,您将获得特定的已创建实例。

由于您的实现是通用的,因此您没有提供足够的信息来注入特定实例。 虽然我没有使用factoryprovider,但我的假设是你需要将Barfactory绑定到一个完全参数化的实例,例如BarImpl而不是BarImpl)

顺便说一句,因为你要绑定BarFactory.class,如果你想绑定多个实例,你将不得不以某种方式用它们来改变它们,比如名字,类似的东西(没有检查语法,但是)

 bind(BarFactory.class).annotatedWith(Names.named("name1")) .toProvider( or by generics, bind(BarFactory).toProvider...