web-dev-qa-db-fra.com

Sous-composants Dagger 2 vs dépendances de composants

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?

117
Bradley Campbell

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.

Dépendance des composants

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

Sous-composant

Notez les points suivants dans l'exemple de sous-composant:

  • Comme 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);
    }
}
205
Praveer Gupta

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 Modules.

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 @Submoduleplus 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.

43
Eugene

Voici l'exemple de code avec capture d'écran pour une meilleure compréhension de Component et SubComponent:

Composant: enter image description here

  1. AppComponent contient deux déclarations.
  2. AppComponent s'initialise dans la classe App.
  3. HomeActivityComponent dépend d'AppComponent.
  4. Dans HomeActivity lors de l'initialisation de DaggerHomeActivityComponent, je donne l'objet AppComponent sous forme de composition.

Sous-composant:

enter image description here

  1. AppComponent contient SubComponent ou SubComponents.
  2. AppComponent s'initialise dans la classe App.
  3. Le sous-composant ne sait pas à propos de son composant parent. Cela ne fournit que ses propres dépendances en incluant Module.
  4. Dans HomeActivity, j'injecte un sous-composant en utilisant son composant parent.

Et le diagramme illustré: enter image description here

Source: lien

11
0xAliHn

Une autre chose que je ne savais pas tout à fait jusqu'à présent, c'est que:

  • UNE @SubcomponentInstance a exactement un composant parent (bien que différents composants puissent instancier ce même @Subcomponent et être le parent de cette instance)
  • UNE @Component peut avoir zéro, un ou plusieurs composants parents déclarés via dépendances des composants
2
arekolek