Question

Total Guice noob here, have read a few articles and seen the intro video, that's about it.

Here's my simplified old code that I'm trying to "guicifiy". Can't quite figure out how to, since (as far as I understand), I can only @inject-annotate one of the two constructors? How can a calling class create the one or the other instance? Or will I have to refactor this somehow?

public class MyDialog extends JDialog {
    public MyDialog( JFrame parent, <other parameters...> ) {
        super( parent );
    }

    public MyDialog( JDialog parent, <other parameters...>) {
        super( parent );
    }
 }
Was it helpful?

Solution

You can only inject into the one ctor.

Depending on how this class is being used, you could:

  • Inject a factory into the client code with two "new" methods.
  • Roll all the arguments into one ctor and pass null when not required.

How can a calling class create the one or the other instance?

This suggests that the calling classes will want multiple instances of MyDialog? Then you need to use a hand-rolled factory (Assisted Inject can handle this for you if you only had one ctor). I don't know the details of what you are up to and I'm likely repeating what you already know but as a blanked statement I'd suggest also extracting an interface from MyDialog and have the factory return them. This way you can fake MyDialog in tests.

OTHER TIPS

Constructor injection is very clean. mlk is right, saying that you can inject into one constructor only.

What you can do is use method injection:

public class Smt {

    private int a;
    private Cereal cereal;
    private Personality personality;
    private ignition;

    public Smt() {
        this.a = 5;
    }

    public Smt(int a) {
        this.a = a;
    }

    @Inject
    public void setup(@CiniMini Cereal cereal, @Rastafarian Personality personality,
        Ignition ignition) {
        this.cereal = cereal;
        this.personality = personality;
        this.ignition = ignition;
    }
}

What Guice will do is call your class' setup class method and provide all the injections. Then you do the same thing as in the constructor--assign the objects to your class' attributes.

I agree with the previous comments. Just an additional hint: constructor injection is supposed to provide all dependencies a class needs. As mlk says, one approach could be to annotate the constructor with most arguments and then refactor the other one to call the former by passing null values where needed.
Additionally, Guice 3.0 supports the so called Constructor Bindings which allow the programmer to specify which constructor to use. See here for more details.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top