Dagger 2 подкомпоненты vs зависимости компонентов

Кинжал 1-х plus() метод-это то, что я использовал довольно часто в предыдущих приложениях, поэтому я понимаю ситуации, когда вы можете захотеть иметь подкомпонент с полным доступом к привязкам родительских графов.

в какой ситуации было бы полезно использовать компонент зависимости вместо зависимость подкомпонент и почему?

4 ответов


зависимости компонентов-используйте это, когда:

  • вы хотите сохранить два независимых компонента.
  • вы хотите явно показать, какие зависимости от одного компонента используются другим

Подкомпоненты-используйте это, когда:

  • вы хотите сохранить два компонента сплоченными
  • вы не можете явно показать, какие зависимости от одного компонента используются другое

я постараюсь показать это на примере. Учитывая, что у нас есть следующие модули и классы. SomeClassB1 зависит от SomeClassA1. Обратите внимание на provideSomeClassB1 метод ModuleB, который показывает эту зависимость.

@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;
    }
}

обратите внимание на следующие моменты в приведенном ниже примере зависимости компонентов:

  • SomeClassB1 зависит от SomeClassA1. ComponentB должен явно определить зависимость.
  • ComponentA не нужно декларировать ModuleB. Это сохраняет независимость двух компонентов.
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();
    }
}

обратите внимание на следующие моменты в Примере Подкомпонента:

  • SomeClassB1 зависит от SomeClassA1. ComponentB не нужно явно определять зависимость.
  • ComponentA признает ModuleB. Это делает два компонента связанными.
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);
    }
}

по словам документация:

Component Dependency предоставляет доступ только к привязкам, предоставляемым как методы предоставления через зависимости компонентов, т. е. у вас есть доступ только к типам, объявленным в parent Component.

SubComponent дает вам доступ к весь привязка графа от его родителя, когда он объявлен, т. е. у вас есть доступ ко всем объектам, объявленным в его Modules.

допустим, у вас есть Ан ApplicationComponent содержащий все Android связанные вещи (LocationService, Resources, SharedPreference и т. д.). Вы также хотите иметь свой DataComponent где вы управляете вещами для настойчивости вместе с WebService для работы с API. Единственное, чего вам не хватает в DataComponent и Application Context который проживает в ApplicationComponent. Самый простой способ получить Context С DataComponent будет зависимость ApplicationComponent. Вы должны быть уверены, что у вас есть Context явно объявлены в ApplicationComponent потому что у вас есть доступ только к объявленным вещам. В этом случай, нет ручной работы, то есть вам не нужно указывать Submodules родитель Component и явно добавьте свой подмодуль в родительский модуль, например:

MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!

теперь рассмотрим тот случай, когда вы хотите ввести WebService С DataComponent и LocationService С ApplicationComponent в своем Fragment, который связывает с помощью @Submodule plus характеристика. Классная вещь здесь заключается в том, что компонент, к которому вы привязываетесь (ApplicationComponent) делает не нужно выставить WebService, ни LocationService потому что у вас есть доступ ко всему графику.


вот пример кода со скриншотом для большего понимания компонента и Подкомпонента:

компоненты: enter image description here

  1. AppComponent содержит два объявления.
  2. AppComponent инициализируется в класс приложения.
  3. HomeActivityComponent зависит от AppComponent.
  4. в HomeActivity при инициализации DaggerHomeActivityComponent я даю объект AppComponent в качестве состав.

подкомпонентов:

enter image description here

  1. AppComponent содержит подкомпонент или Подкомпоненты.
  2. AppComponent инициализируется в класс приложения.
  3. подкомпонент не знает о своем ParentComponent. Это только предоставление собственных зависимостей путем включения модуля.
  4. в HomeActivity я впрыскиваю подкомпонент, используя его Родительский Деталь.

и графическая диаграмма: enter image description here

источник: ссылке


еще одна вещь, которую я не совсем понимал до сих пор, это:

  • A @Subcomponent экземпляр имеет ровно один родительский компонент (хотя разные компоненты могут создавать экземпляры одного и того же @Subcomponent и быть родителем этого экземпляра)
  • A @Component может иметь ноль, один или много родительских компонентов объявлен через зависимостей компонент