java - 使用 Guice 注入(inject)复合 Material

标签 java guice composite

假设我有一个接口(interface)Foo。它由具体实现 CompositeFooFooAFooBFooC 实现。此外,CompositeFoo如下:

public class CompositeFoo implements Foo {
    @Inject public CompositeFoo(List<? extends Foo> elements);
}

我希望在 Guice PrivateModule 中,将 Foo 绑定(bind)到 CompositeFoo,列表为 FooA > 后跟 FooBFooC 等内容。 (这必须是一个列表,因为顺序很重要;这排除了多重绑定(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(FooBFooC)的模块如下:

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/

相关文章:

dependencies - 如何与 Guice 中使用注释值的提供者绑定(bind)?

gwt - 从另一个 Composite 调用 Composite 的 GWT 方法

math - 体积渲染: confusion with front-to-back compositing

java - 在java中使用加密文件而不解密到磁盘

scala - 尝试实例化命名(注释)类

dependency-injection - Play Framework : Dependency Injection inside Action

java - Files.walkFileTree 在 walk/proc 时在访问者方法之外抛出异常

java - new String() 与文字字符串性能

java - 双重依赖注入(inject)和良好实践