Frage

Ich bin ziemlich neu in Guice, also hoffentlich keine offensichtliche Frage ...

Ich habe es mit einem Framework zu tun, das eine meiner Anwendungsklassen dynamisch instanziiert (nennen wir es C) Mit Reflexion habe ich keine Kontrolle über seine Instanziierung. Darüber hinaus gibt es für mich keine einfache Möglichkeit, auf ein neu erstelltes Zugriff aufzunehmen C Nach dem Framework hat es so instanziiert. Hier ist was C würde aussehen wie:

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

Ich möchte C zu erwerben Dependency mit di. Hier Dependency ist eindeutig ein Singleton, aber dies muss im Allgemeinen nicht der Fall sein.

Ich habe zwei mögliche Lösungen entwickelt, von denen keiner sehr ordentlich anfühlt, also dachte ich, ich würde die Experten fragen:

  1. Statische Injektion. Ich habe Schwierigkeiten zu sehen, wie sich dies drastisch über den Service -Locator -Anti -Muster verbessert - ich habe am Ende nicht endgültige statische Felder, die extern manipuliert werden könnten ... Hmmm.

  2. Das Framework unterstützt einen Haken für C um sich nach der Instanziation zu initialisieren (die initialize() oben gezeigte Methode). Diese Methode könnte die neu erstellte Instanz mithilfe der Setter-Injektion selbst injizieren.

Mit 2 denke ich, dass dies mehr externe Veränderbarkeit bedeutet, die Abhängigkeit jedoch zumindest für Dinge wie Unit -Tests ein wenig expliziter enthält. Das Problem ist: Wie bekomme ich den Guice Injector in diesem Fall in die Hände (nicht auf einen weiteren Service -Locator)? Ich habe auch gelesen (und neige dazu, mit zuzustimmen), dass es zweifelhafte Praxis ist, ausdrücklich auf den Injektor während des App -Code zu beziehen.

Ihre Einsicht wäre sehr geschätzt.

Danke vielmals,
Christian

War es hilfreich?

Lösung

Sie könnten versuchen, Anbieter statisch in eine C. statische Injektion zu injizieren, um unangenehmer zu testen. Aber die Anbieter ermöglichen es Guice, Ihre Abhängigkeiten eifrig zu validieren und sie träge zu erstellen.

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();
    ...
  }
}

Andere Tipps

Wenn Sie Ihren Guice Injector durch statische Variable- und statische Accessor -Methoden zur Verfügung stellen, können Sie ihn so lösen:

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

Der statische Anruf ist ein bisschen ein Anti-Muster. Auf diese Weise können Sie alle Objekte injizieren, auch wenn sie keine Initialisierungsmethode haben. Hier finden Sie ein Beispiel dafür: Wie man Modellobjekt mit Aspektjin injiziert.

@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();
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top