玩具示例:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
@Override
public void configure() {
bind(Bar.class).toProvider(new Provider<Bar>() {
@Override public Bar get() {
return foo.getBar();
}
});
}
}
这让我可以懒惰地调用存储在.getBar()
字段中的用户提供的Foo
实例的MyModule
方法。但是现在provider has its own dependencies - 因此我需要定义一个非匿名类,我指定一个@Inject
构造函数。类似的东西:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
@Override
public void configure() {
bind(Bar.class).toProvider(BarProvider.class);
}
BarProvider implements Provider<Bar> {
private Baz baz;
@Inject BarProvider(Baz baz) {
this.baz = baz;
}
@Override public Bar get() {
return foo.getBar(baz);
}
}
}
完美!除了Guice doesn't like this ...
线程“main”com.google.inject.CreationException中的异常:无法创建注入器,请参阅以下错误:
1)不支持注入内部类。请使用'static'类(顶级或嵌套)而不是com.example.MyModule $ BarProvider。
所以,我陷入困境。我需要同时访问模块上的字段和Provider
类的注入类型。有没有办法做到这一点?
注意:这个玩具示例排除了一些实际的复杂性 - 特别是bind()
语句更复杂,这就是为什么我不能简单地定义@Provides
方法
答案 0 :(得分:2)
在某种程度上,注入内部类是不可能的,因为Guice不能反射性地创建没有外部父实例的内部实例(相当于奥术outerInstance.new InnerInstance()
语法)。
一些选项:
getProvider(Class<T>)
方法获取Provider<Baz>
。如果你在创建Injector之前尝试调用它,你会得到一个例外,但是为了按照你正在做的方式创建一个Provider,这可能不是问题。bind
发布到玩具问题之外,看看@Provides
是否有可能带来一些聪明才智。答案 1 :(得分:0)
我意识到我让Guice为我构建我的Provider
,我实际上并不需要这样做。尽管Guice文档中的示例传递DatabaseTransactionLogProvider.class
与第一个片段更好的并行,但是手动构建我的Provider
实例,并传入Foo
实例和{ {1}}实例(provided by the module)。
Provider<Baz>