Ich versuche, meinen Kopf um Bereiche in Dolch 2 zu wickeln, insbesondere um den Lebenszyklus von Diagrammen mit Gültigkeitsbereich. Wie erstellen Sie eine Komponente, die bereinigt wird, wenn Sie den Bereich verlassen?
Bei einer Android-Anwendung haben Sie mit Dagger 1.x im Allgemeinen einen Stammbereich auf Anwendungsebene, den Sie erweitern würden, um einen untergeordneten Bereich auf Aktivitätsebene zu erstellen.
public class MyActivity {
private ObjectGraph mGraph;
public void onCreate() {
mGraph = ((MyApp) getApplicationContext())
.getObjectGraph()
.plus(new ActivityModule())
.inject(this);
}
public void onDestroy() {
mGraph = null;
}
}
Der untergeordnete Bereich bestand, solange Sie einen Verweis darauf aufbewahrten. In diesem Fall war dies der Lebenszyklus Ihrer Aktivität. Durch das Löschen der Referenz in onDestroy wurde sichergestellt, dass das Diagramm mit dem Gültigkeitsbereich frei für die Müllabfuhr war.
BEARBEITEN
Jesse Wilson hat kürzlich einen Mea Culpa veröffentlicht
Dagger 1.0 hat seine Bereichsnamen stark vermasselt ... Die Annotation @Singleton wird sowohl für Stammdiagramme als auch für benutzerdefinierte Diagramme verwendet. Daher ist es schwierig, den tatsächlichen Umfang einer Sache herauszufinden.
und alles andere, was ich gelesen / gehört habe, deutet darauf hin, dass Dolch 2 die Funktionsweise der Bereiche verbessert, aber ich habe Mühe, den Unterschied zu verstehen. Laut dem folgenden Kommentar von @Kirill Boyarshinov wird der Lebenszyklus einer Komponente oder Abhängigkeit wie üblich immer noch durch konkrete Referenzen bestimmt. Ist der Unterschied zwischen den Bereichen Dagger 1.x und 2.0 nur eine Frage der semantischen Klarheit?
Mein Verständnis
Dolch 1.x.
Abhängigkeiten waren entweder @Singleton
oder nicht. Dies galt gleichermaßen für Abhängigkeiten im Stammdiagramm und in den Untergraphen, was zu Unklarheiten darüber führte, an welches Diagramm die Abhängigkeit gebunden war (siehe In Dolch sind Singletons innerhalb des zwischengespeicherten Untergraphen oder werden sie immer neu erstellt, wenn ein neuer Aktivitätsuntergraphen erstellt wird ist gebaut? )
Dolch 2.0
Mit benutzerdefinierten Bereichen können Sie semantisch klare Bereiche erstellen, die jedoch funktional der Anwendung @Singleton
in Dagger 1.x entsprechen.
// Application level
@Singleton
@Component( modules = MyAppModule.class )
public interface MyAppComponent {
void inject(Application app);
}
@Module
public class MyAppModule {
@Singleton @Named("SingletonScope") @Provides
StringBuilder provideStringBuilderSingletonScope() {
return new StringBuilder("App");
}
}
// Our custom scope
@Scope public @interface PerActivity {}
// Activity level
@PerActivty
@Component(
dependencies = MyAppComponent.class,
modules = MyActivityModule.class
)
public interface MyActivityComponent {
void inject(Activity activity);
}
@Module
public class MyActivityModule {
@PerActivity @Named("ActivityScope") @Provides
StringBuilder provideStringBuilderActivityScope() {
return new StringBuilder("Activity");
}
@Name("Unscoped") @Provides
StringBuilder provideStringBuilderUnscoped() {
return new StringBuilder("Unscoped");
}
}
// Finally, a sample Activity which gets injected
public class MyActivity {
private MyActivityComponent component;
@Inject @Named("AppScope")
StringBuilder appScope
@Inject @Named("ActivityScope")
StringBuilder activityScope1
@Inject @Named("ActivityScope")
StringBuilder activityScope2
@Inject @Named("Unscoped")
StringBuilder unscoped1
@Inject @Named("Unscoped")
StringBuilder unscoped2
public void onCreate() {
component = Dagger_MyActivityComponent.builder()
.myApplicationComponent(App.getComponent())
.build()
.inject(this);
appScope.append(" > Activity")
appScope.build() // output matches "App (> Activity)+"
activityScope1.append("123")
activityScope1.build() // output: "Activity123"
activityScope2.append("456")
activityScope1.build() // output: "Activity123456"
unscoped1.append("123")
unscoped1.build() // output: "Unscoped123"
unscoped2.append("456")
unscoped2.build() // output: "Unscoped456"
}
public void onDestroy() {
component = null;
}
}
Das Mitnehmen ist, dass die Verwendung @PerActivity
Ihre Absicht bezüglich des Lebenszyklus dieser Komponente kommuniziert , aber letztendlich können Sie die Komponente überall und jederzeit verwenden. Das einzige Versprechen von Dagger besteht darin, dass für eine bestimmte Komponente mit einem Bereich versehene Methoden eine einzelne Instanz zurückgeben. Ich gehe auch davon aus, dass Dagger 2 die Bereichsanmerkung für die Komponente verwendet, um zu überprüfen, ob Module nur Abhängigkeiten bereitstellen, die entweder im selben Bereich oder nicht im Gültigkeitsbereich liegen.
Zusammenfassend
Abhängigkeiten sind immer noch entweder Singleton- oder Nicht-Singleton-Abhängigkeiten, sind jedoch @Singleton
jetzt für Singleton-Instanzen auf Anwendungsebene vorgesehen, und benutzerdefinierte Bereiche sind die bevorzugte Methode zum Kommentieren von Singleton-Abhängigkeiten mit einem kürzeren Lebenszyklus.
Der Entwickler ist dafür verantwortlich, den Lebenszyklus von Komponenten / Abhängigkeiten zu verwalten, indem er nicht mehr benötigte Referenzen löscht und dafür sorgt, dass Komponenten nur einmal in dem Bereich erstellt werden, für den sie bestimmt sind. Benutzerdefinierte Bereichsanmerkungen erleichtern jedoch die Identifizierung dieses Bereichs .
Die $ 64k Frage *
Ist mein Verständnis der Bereiche und Lebenszyklen von Dolch 2 korrekt?
* Eigentlich keine $ 64'000 Frage.
plus()
Verweises auf ein neues Diagramm in Activity gespeichert und an seinen Live-Zyklus gebunden (dereferenziert inonDestroy
). Die Bereiche stellen sicher, dass Ihre Komponentenimplementierungen beim Kompilieren fehlerfrei generiert werden, wobei jede Abhängigkeit erfüllt ist. Also nicht nur zu Dokumentationszwecken. Schauen Sie sich ein Beispiel aus diesem Thread an .