问题
I have two third-party classes, both of which take an implementation of an Authorizer
interface. I need to inject each with a different implementation.
If I do an @Provides
, how can I implement it so that it provides the implementation required at run time? The provider has no idea who is asking for the injection.
In theory I could use @Named
, but I can't modify the code being injected. I want to do something like:
bind(Authorizer.class).to(ImplA.class).for(SomeClass.class)
bind(Authorizer.class).to(ImplB.class).for(SomeOtherClass.class)
Obviously, the "for" code doesn't exist, but is there some equivalent way to do this?
回答1:
You can achieve this using Private Modules, which let you install (mutually-inaccessible) conflicting bindings to be used in constructing a limited set of non-conflicting exposed bindings. This is often seen as a solution to the robot legs problem, in which you'd want to (for instance) expose a @Left Leg
and a @Right Leg
where the Leg
object is exactly the same but you've bound different Foot
implementations (LeftFoot
and RightFoot
) further down in the hierarchy.
At this point, you're not specifying "who is getting it", but you're exposing a slightly different Injector graph for one consumer versus the other.
install(new PrivateModule() {
bind(Authorizer.class).to(ImplA.class);
expose(SomeClass.class);
});
install(new PrivateModule() {
bind(Authorizer.class).to(ImplB.class);
expose(SomeOtherClass.class);
});
来源:https://stackoverflow.com/questions/36186724/guice-inject-different-implementation-depending-on-who-is-getting-it