2016-04-07 9 views
5

Ich habe ein Guice-basiertes Projekt mit Vanille Guice; kein Assisted-Inject, kein AOP, kein zusätzliches Plugin zur Erweiterung von Guice, etc. Um es einfacher unter Android laufen zu lassen, scheint Dolch eine bessere Lösung zu sein. Jede Klasse hat eine Abhängigkeit und einen Konstruktor mit @Inject Annotation. Es wird keine Feld- oder Methodeninjektion verwendet.Migrieren eines Guice-basierten Projekts zu Dagger

Die Module ganz einfach sind (was Guice zuviel des Guten) und enthalten meist Bindungen wie folgt aus:

class SomethingModule extends AbstractModule { 

    protected void configure() { 
    Bind(Handler.class) 
     .annotatedWith(Names.named("something")) 
     .to(SomeImplementation.class); 
    } 
    } 

} 

Und später verwendet wie folgt aus:

Injector inj = Guice.createInjector(new SomethingModule()); 
... = inj.getInstance(SampleInterface.class); 
// and rest of the code. 

Leider kann ich nicht bekomme meinen Kopf um Daggers terminology. Kannst du mich mit einer direkten Übersetzung/Transformation eines Guice-Moduls zu einem Dagger-Modul führen?

Dagger hat:

  • Dolch der Komponenten.
  • Dolch-Module.
  • @Provides
  • @Inject

Guice hat:

  • @Inject
  • @Named (oder irgendeine benutzerdefinierte Anmerkung, wenn es richtig implementiert).
  • Unsere Module erweitern AbstractModule.
  • @Provides in den Modulen.
  • Guice Injector erstellt von Modulen.

Wie hängen diese zusammen?

Update: Zusätzlich zu der netten Antwort von EpicPandaForce kann these slides auch helfen.

Antwort

3
Bind(Handler.class) 
.annotatedWith(Names.named("something")) 
.to(SomeImplementation.class); 

Würde zu

@Module 
public class SomethingModule { 
    @Provides 
    @Named("something") 
    //scope if needed 
    public Handler handler() { 
     return new SomeImplementation(); 
    } 
} 

übersetzen, die zu einer "Injector" (Komponente) gebunden werden würde:

@Component(modules={SomethingModule.class}) 
//scope if needed 
public interface SomethingComponent { 
    @Named("something") 
    Handler handler(); 

    void inject(ThatThingy thatThingy); 
} 

die ein "Injektor" ist, dass Sie mit dem erstellen müssen APT-generierter Builder:

SomethingComponent somethingComponent = DaggerSomethingComponent.builder() 
              .somethingModule(new SomethingModule()) //can be omitted, has no params 
              .build(); 
somethingComponent.inject(thatThingy); 

Wo das thingy existieren hat

public class ThatThingy { 
    @Inject 
    @Named("something") 
    Handler handler; 
} 

Komponenten typischerweise pro Umfang, so beispielsweise eine @ApplicationScope "Injektor" (Komponente) aufweist. Scoping kann mit Unterkomponenten und Komponentenabhängigkeiten erreicht werden.

Wichtige Tatsache, eine Komponente hat Provisionierungsmethoden (das sind die Abhängigkeiten, die an subscoped Komponenten geerbt werden, wenn Sie Komponent Abhängigkeiten verwenden) und void inject(X x); formatierte Methoden. Dies ist erforderlich für die Feldinjektion pro Betontyp. Eine Basisklasse kann beispielsweise nur selbst und nicht ihre Unterklassen injizieren. Sie können jedoch eine Methode namens protected abstract void injectThis() schreiben, die auch die .inject(this) für die Unterklasse aufrufen würde.

Da ich Guice nicht wirklich benutzt habe, bin ich mir nicht sicher, ob ich etwas verpasst habe. Ich glaube, ich habe die Konstruktorinjektion vergessen, was ein Problem ist, da Dagger es zwar nicht unterstützt, aber nicht neu konfiguriert werden kann. Für die Rekonfiguration müssen Sie Module verwenden und die Injektion in den Konstruktoren selbst durchführen.

@Module(includes={ThoseModule.class, TheseModule.class}) 
public class SomethingModule { 
    @Provides 
    @Singleton 
    public Whatever whatever(Those those, These these) { 
     return new Whatever(those, these); 
    } 
} 

public class Whatever { 
    Those those; 
    These these; 

    public Whatever(Those those, These these) { 
     this.those = those; 
     this.these = these; 
    } 
} 

@Component(modules={SomethingModule.class}) 
@Singleton 
public interface SomethingComponent { 
    These these(); 
    Those those(); 
    Whatever whatever(); 
} 
+1

Nitpick: a näher Dagger Äquivalent 'bind (X.class) .DE (Y.class)' 'ist @Provides ProvideX X (Y y) {y zurückzukehren; } ' –

+1

@TavianBarnes aber wo würde das Modul eine Instanz von 'Y' erhalten? Du musst es irgendwo erstellen. – EpicPandaForce

+2

Wenn 'Y' einen '@ Inject'-Konstruktor hat, wird dieser automatisch aufgerufen –