假设我有一个接口(interface)Foo
。它由具体实现 CompositeFoo
、FooA
、FooB
和 FooC
实现。此外,CompositeFoo
如下:
public class CompositeFoo implements Foo {
@Inject public CompositeFoo(List<? extends Foo> elements);
}
我希望在 Guice PrivateModule
中,将 Foo
绑定(bind)到 CompositeFoo
,列表为 FooA
> 后跟 FooB
或 FooC
等内容。 (这必须是一个列表,因为顺序很重要;这排除了多重绑定(bind)作为解决方案。)
问题是我发现其中存在一些循环。假设CompositeFoo
的提供者如下:
public class CompositeFooProvider implements Provider<Foo> {
@Inject private FooA first;
@Inject @Named("Inner") private Foo second;
@Override public Foo get() { return new CompositeFoo(asList(first, second)); }
}
提供第二个 Foo
(FooB
或 FooC
)的模块如下:
public class InnerModule extends PrivateModule {
private final Key<? super Foo> bindingKey; // key will be exposed, bound to the Foo below
// configure() deals with deps of FooB and FooC
@Provides
public Foo getInnerFoo(...) {
// Assume that the args are such that if they are "valid", we should return a FooB, else FooC
if (...) return new FooB(...);
else return new FooC(...);
}
}
当我尝试构造外部模块时,就会出现循环:我需要安装 InnerModule
(传入 Key.get(Foo.class, Names.named("Inner") )
作为绑定(bind)键)以获取第二个 Foo
,但 Foo
由于绑定(bind)到 而已经绑定(bind)在外部模块中CompositeFooProvider
。如何解决这个循环?将 @Provides
方法转换为其自己的 Provider
就足够了吗?
最佳答案
@Provides Foo
方法为 Foo
提供绑定(bind),这与外部模块中的 Foo
绑定(bind)冲突。因此将其绑定(bind)为其他内容:
public class InnerModule extends PrivateModule {
private final Key<Foo> bindingKey; // key will be exposed, bound to the @Inner Foo below
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
@interface Inner {
}
@Override
protected void configure() {
bind(bindingKey).to(Key.get(Foo.class, Inner.class));
expose(bindingKey);
}
@Provides
@Inner Foo getInnerFoo(...) {
// Assume that the args are such that if they are "valid", we should return a FooB, else FooC
if (...) return new FooB(...);
else return new FooC(...);
}
}
或者也许你可以这样做
@Provides
@Exposed
@Named("Inner") Foo getInnerFoo(...) {
// Assume that the args are such that if they are "valid", we should return a FooB, else FooC
if (...) return new FooB(...);
else return new FooC(...);
}
直接,不用费心传递绑定(bind) key 。
关于java - 使用 Guice 注入(inject)复合 Material ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26939304/