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
- You will need two instances of PrivateModule, one each for B1 and B2
- Bind B to the appropriate concrete type
expose(A.class).annotatedWith(B1.class)
http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/PrivateModule.html
-dg
精彩评论