2009-12-03 11 views
2

Total Guice noob ici, ont lu quelques articles et vu la vidéo d'introduction, c'est à peu près tout.Comment injecter avec Guice quand il y a deux constructeurs différents?

Voici mon ancien code simplifié que j'essaie de "guicifier". Je n'arrive pas à comprendre comment, puisque (pour autant que je sache), je peux seulement @inject -annoter l'un des deux constructeurs? Comment une classe appelante peut-elle créer l'une ou l'autre instance? Ou devrais-je refactoriser cela d'une manière ou d'une autre?

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

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

Répondre

4

Vous ne pouvez injecter que dans un seul ctor.

Selon la façon dont cette classe est utilisé, vous pouvez:

  • Injecter une usine dans le code client avec deux méthodes « nouvelles ».
  • Roulez tous les arguments dans un seul ctor et passez la valeur null lorsque cela n'est pas nécessaire.

Comment une classe appelante peut-elle créer l'une ou l'autre instance?

Ceci suggère que les classes appelantes voudront plusieurs instances de MyDialog? Ensuite, vous devez utiliser une usine laminée à la main (Assisted Inject peut gérer cela pour vous si vous avez seulement un ctor). Je ne connais pas les détails de ce que vous faites et je répète sans doute ce que vous savez déjà, mais en guise de déclaration, je suggèrerais également d'extraire une interface de MyDialog et que l'usine les renvoie. De cette façon, vous pouvez simuler MyDialog dans les tests.

1

L'injection du constructeur est très propre. mlk a raison, disant que vous pouvez injecter dans un seul constructeur.

Qu'est-ce que vous pouvez faire est l'injection de méthode d'utilisation:

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; 
    } 
} 

Qu'est-ce que Guice va faire est d'appeler votre méthode de classe de classe setup et de fournir toutes les injections. Ensuite, vous faites la même chose que dans le constructeur - assignez les objets aux attributs de votre classe.

0

Je suis d'accord avec les commentaires précédents. Juste un indice supplémentaire: l'injection du constructeur est censée fournir toutes les dépendances dont une classe a besoin. Comme le dit mlk, une approche pourrait consister à annoter le constructeur avec la plupart des arguments et ensuite refactoriser l'autre pour appeler le premier en passant des valeurs nulles si nécessaire.
En outre, Guice 3.0 prend en charge les relations constructeur qui permettent au programmeur de spécifier le constructeur à utiliser. Voir here pour plus de détails.