Hi,
correct me if I am wrong guys,
The point is here
static class Leg {
@Inject Foot foot;
Notice you're injecting a Foot but how do you know which Foot?
You can't to
static class Leg {
@Inject @Left @Right Foot foot;
that makes no sense
static class Robot {
@Inject @Left Leg leftLeg;
@Inject @Right Leg rightLeg;
Now you can't do
bind(Foot.class).to(new Foot("Lefty")).ifParentAnnotatedWith
(Left.class);
bind(Foot.class).to(new Foot("Righty")).ifParentAnnotatedWith
(Right.class);
but notice how with Private Module you can get this functionality.
I've been playing around with this and made an example using a Car
maybe that will be clearer. I get confused with Feet and Leg on first
reading.
Cheers,
Alen
/////////////////////////////////////////////////////////////////////////////////
import com.google.inject.*;
import com.google.inject.privatemodules.PrivateModule;
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Date;
public class RobotLegsProblem2 {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule()
{
@Override
protected void configure() {
// global stuff
// same to all
bind(Driveline.class).to(FrontWheelDrive.class);
bind(Engine.class).to(DieselEngine.class);
}
}, new PrivateModule() {
@Override
protected void configurePrivateBindings() {
// private Module is different story
// Bind car annotated with blue and expose it
bind(Car.class).annotatedWith(Blue.class).to
(Car.class);
expose(Car.class).annotatedWith(Blue.class);
// What we bind in here only applies to the exposed
stuff
// i.e. the exposed car from this module will get this
injected
// where stuff in regular module (Engine,Driveline) is
"inherited" - it is global
bind(Transmission.class).to
(AutomaticTransmission.class);
}
}, new PrivateModule() {
@Override
protected void configurePrivateBindings() {
bind(Car.class).annotatedWith(Red.class).to
(Car.class);
expose(Car.class).annotatedWith(Red.class);
bind(Transmission.class).to(ManualTransmission.class);
// The point is that you cannot do this with regular
module i.e.
// bind(Car.class).annotatedWith(Blue.class).to
(Car.class);
// bind(Car.class).annotatedWith(Red.class).to
(Car.class);
// now notice the dilemma
// class Car{
// @Inject Transmission transmission;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// You cannot solve this by
// @Inject @Blue @Red Transmission transmission;
// or
// bind(Transmission.class).to
(AutomaticTransmission.class).ifParentAnnotatedWith(Blue.class)
// bind(Transmission.class).to
(ManualTransmission.class).ifParentAnnotatedWith(Red.class)
// but with private modules you can get this
functionality
}
});
Car blueCar = injector.getInstance(Key.get(Car.class,
Blue.class));
System.out.println("Blue car transmission: " +
blueCar.getTransmission());
Car redCar = injector.getInstance(Key.get(Car.class,
Red.class));
System.out.println("Red car transmission: " +
redCar.getTransmission());
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, PARAMETER, METHOD})
@BindingAnnotation
@interface Blue {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, PARAMETER, METHOD})
@BindingAnnotation
@interface Red {
}
class Car {
private final Engine engine;
private final Transmission transmission;
private final Driveline driveline;
@Inject
public Car(Engine engine, Transmission transmission, Driveline
driveline) {
this.engine = engine;
this.transmission = transmission;
this.driveline = driveline;;
}
public Driveline getDriveline() {
return driveline;
}
public Engine getEngine() {
return engine;
}
public Transmission getTransmission() {
return transmission;
}
}
interface Transmission {
}
class AutomaticTransmission implements Transmission {
}
class ManualTransmission implements Transmission {
}
interface Engine {
}
class DieselEngine implements Engine {
}
class PetrolEngine implements Engine {
}
interface Driveline {
}
class FourWheelDrive implements Driveline {
}
class FrontWheelDrive implements Driveline {
}
class RearWheelDrive implements Driveline {