Зависимости компонентов - используйте этот параметр, если хотите сохранить независимость двух компонентов.
Субкомпоненты - используйте это, если вы хотите соединить два компонента.
Я буду использовать приведенный ниже пример для объяснения зависимостей компонентов и подкомпонентов . Вот некоторые моменты, на которые стоит обратить внимание:
SomeClassA1
может быть создан без какой-либо зависимости. ModuleA
предоставляет и экземпляр SomeClassA1
через provideSomeClassA1()
метод.
SomeClassB1
не может быть создан без SomeClassA1
. ModuleB
может предоставить экземпляр, SomeClassB1
только если экземпляр SomeClassA1
передается в качестве аргумента 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 позаботится о передаче экземпляра SomeClassA1
в качестве аргумента provideSomeClassB1()
методу при ModuleB
каждой ModuleB
инициализации объявления компонента / субкомпонента . Нам нужно проинструктировать Кинжал, как выполнить зависимость. Это можно сделать с помощью зависимости компонента или субкомпонента .
Компонентная зависимость
Обратите внимание на следующие моменты в приведенном ниже примере зависимости компонента:
ComponentB
должен определить зависимость через dependencies
метод @Component
аннотации.
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();
}
}
субкомпонент
Обратите внимание на следующие моменты в примере SubComponent:
- Поскольку
ComponentB
не определила зависимость от ModuleA
нее, она не может жить самостоятельно. Это становится зависимым от компонента, который обеспечит ModuleA
. Следовательно, у него есть @Subcomponent
аннотация.
ComponentA
объявил ModuleB
через метод интерфейса componentB()
. Это объединяет два компонента. На самом деле, ComponentB
может быть инициализирован только через 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);
}
}
SomeClassB1
зависит отSomeClassA1
.ComponentA
должен явно определить зависимость.» ==> Вы имели в виду «ComponentB
должен явно определять зависимость»?SomeClassB1
зависит отSomeClassA1
. НеComponentA
нужно явно определять зависимость». Вы имели в виду «ComponentB
не нужно явно определять зависимость».Согласно документации :
Component Dependency
дает вам доступ только к привязкам, предоставляемым в качестве методов предоставления через зависимости компонентов, т.е. у вас есть доступ только к тем типам, которые объявлены в parentComponent
.SubComponent
дает вам доступ ко всему графу связывания от его родителя, когда он объявлен, т.е. у вас есть доступ ко всем объектам, объявленным в егоModule
s.Скажем, у вас есть ,
ApplicationComponent
содержащее всеAndroid
родственное вещество (LocationService
,Resources
,SharedPreference
и т.д.). Вы также хотите, чтобыDataComponent
вы постоянно управляли вещами, а также имелиWebService
дело с API. Единственное, чего тебе не хватаетDataComponent
этоApplication Context
что находится вApplicationComponent
. Самый простой способ получитьContext
отDataComponent
- это зависимостьApplicationComponent
. Вы должны быть уверены, что у вас естьContext
явное объявление,ApplicationComponent
потому что у вас есть доступ только к объявленным вещам. В этом случае нет ручной работы, то есть вам не нужно указыватьSubmodules
в parentComponent
и явно добавлять свой подмодуль в родительский модуль, например:Теперь рассмотрим тот случай, когда вы хотите ввести
WebService
изDataComponent
иLocationService
изApplicationComponent
в ваш,Fragment
который связывает с помощью@Submodule
plus
функции выше. Крутая вещь здесь заключается в том, что компонент, к которому вы привязываете (ApplicationComponent
), не нужно раскрыватьWebService
ниLocationService
потому, что у вас есть доступ ко всему графику сразу.источник
@Submodule
. Это опечатка?classes
примеров и больше картинок, чтобы проиллюстрировать точную точку зрения.Вот пример кода со скриншотом для лучшего понимания Компонента и Подкомпонента:
Составная часть:
подкомпоненте:
И наглядная схема:
Источник: ссылка
источник
Еще одна вещь, которую я до сих пор не осознавал, это то, что:
@Subcomponent
Экземпляр имеет ровно один родительский компонент (хотя различные компоненты могут создать экземпляр в том же@Subcomponent
и быть родителем этого экземпляра)@Component
может иметь ноль, один или несколько «родительских» компонентов, объявленных через зависимости компонентовисточник