La méthode plus()
de Dagger 1 est quelque chose que j'ai souvent utilisé dans les applications précédentes. Je comprends donc les situations dans lesquelles vous souhaiterez peut-être avoir un sous-composant avec un accès complet aux liaisons des graphes parents.
Dans quelle situation serait-il avantageux d'utiliser un dépendance des composants au lieu de dépendance des sous-composants et pourquoi?
Dépendances des composants - Utilisez cette option pour conserver deux composants indépendants.
Sous-composants - À utiliser lorsque vous souhaitez conserver deux composants couplés.
Je vais utiliser l'exemple ci-dessous pour expliquer dépendances de composants et sous-composants. Certains points à noter à propos de l'exemple sont les suivants:
SomeClassA1
Peut être créé sans aucune dépendance. ModuleA
fournit une instance de SomeClassA1
via la méthode provideSomeClassA1()
.SomeClassB1
Ne peut être créé sans SomeClassA1
. ModuleB
peut fournir une instance de SomeClassB1
uniquement si une instance de SomeClassA1
est transmise en tant qu'argument à la méthode provideSomeClassB1()
.@Module
public class ModuleA {
@Provides
public SomeClassA1 provideSomeClassA1() {
return new SomeClassA1();
}
}
@Module
public class ModuleB {
@Provides
public SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) {
return new SomeClassB1(someClassA1);
}
}
public class SomeClassA1 {
public SomeClassA1() {}
}
public class SomeClassB1 {
private SomeClassA1 someClassA1;
public SomeClassB1(SomeClassA1 someClassA1) {
this.someClassA1 = someClassA1;
}
}
Dagger se chargera de transmettre l'instance de SomeClassA1
En tant qu'argument à la méthode provideSomeClassB1()
sur ModuleB
à chaque fois que le composant/sous-composant déclarant ModuleB
sera initialisé. Nous devons apprendre à Dagger comment remplir cette dépendance. Cela peut être fait en utilisant dépendance des composants ou sous-composant.
Notez les points suivants dans l'exemple de dépendance Component ci-dessous:
ComponentB
doit définir la dépendance via la méthode dependencies
sur l'annotation @Component
.ComponentA
n'a pas besoin de déclarer ModuleB
. Cela maintient les deux composants indépendants.public class ComponentDependency {
@Component(modules = ModuleA.class)
public interface ComponentA {
SomeClassA1 someClassA1();
}
@Component(modules = ModuleB.class, dependencies = ComponentA.class)
public interface ComponentB {
SomeClassB1 someClassB1();
}
public static void main(String[] args) {
ModuleA moduleA = new ModuleA();
ComponentA componentA = DaggerComponentDependency_ComponentA.builder()
.moduleA(moduleA)
.build();
ModuleB moduleB = new ModuleB();
ComponentB componentB = DaggerComponentDependency_ComponentB.builder()
.moduleB(moduleB)
.componentA(componentA)
.build();
}
}
Notez les points suivants dans l'exemple de sous-composant:
ComponentB
n'a pas défini la dépendance sur ModuleA
, il ne peut pas vivre indépendamment. Cela devient dépendant du composant qui fournira le ModuleA
. Par conséquent, il possède une annotation @Subcomponent
.ComponentA
a déclaré ModuleB
via la méthode d'interface componentB()
. Cela rend les deux composants couplés. En fait, ComponentB
ne peut être initialisé que par ComponentA
.public class SubComponent {
@Component(modules = ModuleA.class)
public interface ComponentA {
ComponentB componentB(ModuleB moduleB);
}
@Subcomponent(modules = ModuleB.class)
public interface ComponentB {
SomeClassB1 someClassB1();
}
public static void main(String[] args) {
ModuleA moduleA = new ModuleA();
ComponentA componentA = DaggerSubComponent_ComponentA.builder()
.moduleA(moduleA)
.build();
ModuleB moduleB = new ModuleB();
ComponentB componentB = componentA.componentB(moduleB);
}
}
Selon le documentation :
Component Dependency
vous donne accès uniquement aux liaisons exposées en tant que méthodes de provision via des dépendances de composant, c’est-à-dire que vous n’avez accès qu’aux types déclarés dans le parent Component
.
SubComponent
vous donne un accès au graphe de liaison entier depuis son parent lorsqu'il est déclaré, c'est-à-dire que vous avez un accès à tous les objets déclarés dans son Module
s.
Supposons que vous avez un ApplicationComponent
contenant tous les éléments associés à Android
(LocationService
, Resources
, SharedPreference
, etc.). Vous voulez également avoir votre DataComponent
où vous gérez les choses pour la persistance avec WebService
pour gérer les API. La seule chose qui vous manque dans DataComponent
est Application Context
qui réside dans ApplicationComponent
. Le moyen le plus simple d'obtenir un Context
à partir de DataComponent
serait de dépendre de ApplicationComponent
. Vous devez vous assurer que vous avez un Context
explicitement déclaré dans ApplicationComponent
parce que vous n’avez accès qu’aux fichiers déclarés. Dans ce cas, il n'y a pas de travail manuel, ce qui signifie que vous n'avez pas besoin de spécifier Submodules
dans le parent Component
et d'ajouter explicitement votre sous-module à un module parent comme:
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
Considérons maintenant le cas où vous souhaitez injecter WebService
de DataComponent
et LocationService
de ApplicationComponent
dans votre Fragment
qui se lie à l'aide de la commande @Submodule
plus
caractéristique ci-dessus. La chose intéressante ici est que le composant que vous liez (ApplicationComponent
) fait pas devez exposer WebService
ni LocationService
parce que vous avoir accès au graphique entier tout de suite.
Voici l'exemple de code avec capture d'écran pour une meilleure compréhension de Component et SubComponent:
Sous-composant:
Source: lien
Une autre chose que je ne savais pas tout à fait jusqu'à présent, c'est que:
@Subcomponent
Instance a exactement un composant parent (bien que différents composants puissent instancier ce même @Subcomponent
et être le parent de cette instance)@Component
peut avoir zéro, un ou plusieurs composants parents déclarés via dépendances des composants