开发者

Guice: Building Related Trees of Objects / Robot Legs

I have a class A that holds a class B like this:

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) { }
}

I'd like to bind two different A's, one annotated @AhasB1 and another @AhasB2. How can I开发者_如何学运维 bind these correctly?


Here's how I did it using 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);
            }
        });
}


Instead of using @Provides methods, consider a set of Provider<A> types, possibly nested in the type A, granting you access to the private ctor. Or make it a package-protected ctor, and put the providers in the same package as it. Or, of course, you could move your Module type into the same package as A.

Another option would be AssistedInject, which would allow you to specify a set of methods that would, based on name or param, would return different instances (in your case, probably subtypes of A). I think it will have access to private constructors.

One last thought for you: Why not leave the constructor to A as public, so that a user of the library can manually inject dependencies? If this is for internal use only, documenting the ctor could also suffice.


I think the solution you are looking for is Private Modules

  1. You will need two instances of PrivateModule, one each for B1 and B2
  2. Bind B to the appropriate concrete type
  3. expose(A.class).annotatedWith(B1.class)

http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/PrivateModule.html

-dg

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜