Question

Je suis assez nouveau pour Guice si nous espérons que ce n'est pas une question évidente ...

Je fais face à un cadre qui instancie dynamiquement un de mes cours d'application (Appelons-le C) utilisant la réflexion, donc je ne contrôle pas son instanciation. De plus, il n'y a aucun moyen facile pour moi d'accéder à un C nouvellement créé après que le cadre a instantitated il. Voici ce que C ressemblerait à ceci:

    public class C implements I {

        public C() {
            // this ctor is invoked by the framework so can't use DI here?
        }        

        public void initialize() {
            // this is a post instantiation hook which the f/w will invoke
        }

        private void m() {
            Dependency d = Dependency.getInstance();
            d.doSmth();
        }
    }

Je voudrais C à acquérir Dependency en utilisant DI. Ici Dependency est clairement un singleton, mais cela ne doit pas être le cas en général.

Je suis venu avec deux solutions possibles, dont aucun ne se sent très bien rangé, donc je pensais que je demande aux experts:

  1. injection statique. Je lutte pour voir comment cela améliore considérablement sur le service de localisation anti-modèle si -. Je finis avec des champs statiques non finales qui pourraient être à l'extérieur ... hmmm manipulables

  2. Le cadre supporte un crochet pour C s'initialiser instanciation après (la méthode de initialize() ci-dessus). Cette méthode pourrait auto-inject l'instance nouvellement créée par injection setter.

Avec 2, je suppose que cela signifie altérabilité plus externe, mais au moins la dépendance expose un peu plus explicitement pour des choses comme des tests unitaires. Le problème est: comment puis-je obtenir mes mains sur le Injector Guice dans ce cas (à court de compter sur un autre localisateur de service)? Je l'ai lu aussi (et d'accord avec) que se référant explicitement à l'injecteur à travers le code de l'application est pratique douteuse.

Votre perspicacité serait vraiment apprécié.

Merci,
Christian

Était-ce utile?

La solution

Vous pouvez essayer l'injection statiquement fournisseurs dans C. injection statique plus difficile à tester. Mais les fournisseurs permettent de Guice pour valider vos dépendances avec impatience, tout en les créant paresseusement.

public class C implements I {
  @Inject static Provider<Dep1> dep1Provider;
  @Inject static Provider<Dep2> dep2Provider;

  ...

  public void initialize() {
    Dep1 dep1 = dep1Provider.get();
    Dep2 dep2 = dep2Provider.get();
    ...
  }
}

Autres conseils

Si vous faites votre Guice injecteur disponible par la variable statique et les méthodes accesseurs statiques vous pouvez le résoudre comme ceci:

public class C implements I {

    public C() {
        // this ctor is invoked by the framework, you can't do injection here.
    }        

    public void initialize() {
        MyGuice.getInjector().inject(this);
    }

    @Inject
    protected void init(Dep1 dep1, Dep2 dep2) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    private void m() {
        dept1.doSmth();
    }
}

L'appel statique est un peu d'un anti-modèle, vous pouvez supprimer cette dépendance avec une simple annotation qui prend soin de l'injection après constructeur si vous êtes prêt à utiliser une solution qui fait le tissage de code ou d'une étape de post-compilation. De cette façon, vous pouvez injecter tous les objets même si elles ne sont pas une méthode d'initialisation. Vous pouvez trouver un exemple ici. Comment injecter modèle objet avec AspectJ

@Configurable
public class C implements I {

    public C() {
        // this ctor is invoked by the framework, you can't do injection here.
    }        

    @Inject
    protected void init(Dep1 dep1, Dep2 dep2) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    private void m() {
        dept1.doSmth();
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top