Guice:构建相关的物体树/机器人腿

时间:2011-07-15 14:26:31

标签: dependency-injection annotations guice robot-legs-problem

我有一个A类,它持有这样的B类:

class A {
   private final B b;
   @Inject
   A(B b) {
     this.b = b;
   }
}

interface B {}
class B1 implements B {}
class B2 implements B {}

class Client() {
   @Inject 
   Client(@AhasB1 A aHasB1, @AhasB2 A aHasB2) { }
}

我想绑定两个不同的A,一个注释@AhasB1和另一个@AhasB2。我怎样才能正确绑定这些?

3 个答案:

答案 0 :(得分:3)

以下是我使用PrivateModule的方式。

public class MainModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new PrivateModule(){
            @Override
            protected void configure() {
                bind(A.class).annotatedWith(AhasB1.class).to(A.class);
                expose(A.class).annotatedWith(AhasB1.class);
                bind(B.class).to(B1.class);
            }
        });

        install(new PrivateModule(){
            @Override
            protected void configure() {
                bind(A.class).annotatedWith(AhasB2.class).to(A.class);
                expose(A.class).annotatedWith(AhasB2.class);
                bind(B.class).to(B2.class);
            }
        });
}

答案 1 :(得分:1)

不要使用@Provides方法,而应考虑一组Provider<A>类型,可能嵌套在类型A中,授予您访问私有ctor的权限。或者使它成为受包保护的ctor,并将提供者放在与它相同的包中。或者,当然,您可以将模块类型移动到与A相同的包中。

另一个选项是AssistedInject,这将允许您指定一组方法,这些方法将基于名称或参数返回不同的实例(在您的情况下,可能是A的子类型)。我认为它可以访问私人构造函数。

最后一个想法:为什么不将构造函数保留为A公共,以便库的用户可以手动注入依赖项?如果这仅供内部使用,记录ctor也足够了。

答案 2 :(得分:1)

我认为您正在寻找的解决方案是私有模块

  1. 您需要两个PrivateModule实例,分别用于B1和B2
  2. 将B绑定到适当的具体类型
  3. expose(A.class).annotatedWith(B1.class)
  4. http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/PrivateModule.html

    -dg