Dagger 2 имеет функцию подкомпонент. Есть два способа создать подкомпонент. Я буду сравнивать их рядом

Синтаксис создания

1. Через родительский компонент

@Component
interface ParentComponent {
    val childComponent: ChildComponent
}

Используя этот подход, мы также могли бы получить доступ к ChildComponent’s Builder.

@Component
interface ParentComponent {
    val childComponentBuilder: ChildComponent.Builder
}

Примечание: когда использовать Builder или не ссылаться на этот блог.

2. Через родительский модуль

@Module(subcomponents = [ChildComponent::class])
class ParentModule
@Component(modules = [ParentModule::class])
interface ParentComponent

Сравнение

1. Ленивое создание ChildComponent

  • Через ParentComponent всегда будет создан ChildComponent (или Builder), независимо от того, используется он или нет ❎
  • Через ParentModule ChildComponent будет создан только тогда, когда он понадобится (зависит от) ✅

2. Необходимость ChildComponent.Builder

  • Через ParentComponent нам не нужно иметь явный конструктор дочернего компонента (если только ParentComponent не запрашивает конструктор дочернего компонента) ✅
  • Через ParentModule для ChildComponent необходимо явно указать Builder ❎
@Subcomponent(modules = [ChildModule::class])
interface ChildComponent {
    @Subcomponent.Builder
    interface Builder {
        fun build(): ChildComponent
    }
}

3. Семантическая корректность

  • Через ParentComponent это более семантически корректно, так как весь модуль Parent сможет получить доступ к Subcomponent ✅
  • Через ParentModule он становится менее семантически правильным, поскольку даже если подкомпонент указан в ParentModule1, но он по-прежнему доступен через ParentModule2 ❎
@Module(subcomponents = [ChildComponent::class])
class ParentModule1
@Module
class ParentModule2 // Can still access to ChildComponent
@Component(modules = [ParentModule1::class, ParentModule2::class])
interface ServerComponent

4. Внешний доступ к ChildComponent

  • Через ParentComponent внешний код, не связанный внутри Dagger Component, может получить доступ к ChildComponent ✅
@Singleton
@Component
interface ParentComponent {
    val childComponent: ChildComponent
}
fun main() {
    // External code access the child component.
    DaggerPareentComponent.create().childComponent 
}
  • Через ParentModule внешний код, не связанный с компонентом Dagger, не мог получить доступ к ChildComponent ❎

Конечно, у вас может быть гибрид, как показано ниже. В этом случае вам нужно иметь Builder вместо ChildComponent (поскольку нам нужно, чтобы Builder был определен в ChildComponent согласно сравнению 2 выше).

@Module(subcomponents = [ChildComponent::class])
class ParentModule
@Component(modules = [ParentModule::class])
interface ParentComponent {
    val childComponentBuilder: ChildComponent.Builder
}

Это также делает subcomponents = [ChildComponent::class] избыточным.

5. Внедрение модулей в подкомпонент

  • Через ParentComponent у нас все еще может быть внедрение модуля в Subcomponent без Builder ✅
@Module(subcomponents = [ChildComponent::class])
class ParentModule
@Component(modules = [ParentModule::class])
interface ParentComponent {
    fun childComponent(childModule: ChildModule): ChildComponent
}

Конечно, если у нас есть доступ к Builder ChildComponent, то это можно сделать через Builder, как показано ниже.

  • Через ParentModule нам нужно явно указать API для внедрения модуля. Я считаю это шаблонным по сравнению с предыдущим ❎
@Subcomponent(modules = [ChildModule::class])
interface ChildComponent {
    @Subcomponent.Builder
    interface Builder {
        fun childModule(childModule: ChildModule): Builder
        fun build(): ChildComponent
    }
}

6. Обратная зависимость (зависимость дочернего компонента родительского доступа)

Об этом подробно рассказывается в статье ниже. Оба могут это сделать.



TL;DR

Ниже будет моя рекомендация

  1. Если ваш ChildComponent должен иметь доступ по внешнему коду (не привязанному к Dagger 2), тогда создайте Subcomponent через ParentComponent
  2. Если ваш ChildComponent определенно используется, вам не нужно его лениво создавать, а затем создавать Subcomponent через ParentComponent
  3. Если ваш ChildComponent используется только изредка и все к нему имеют доступ только объекты, которые ограничены ParentComponent, тогда создайте Subcomponent через ParentModule.

Спасибо за чтение. Вы можете ознакомиться с другими моими темами здесь.

Подпишитесь на меня в medium, Twitter, Facebook или Reddit, чтобы получить советы и узнать о мобильной разработке и т. Д., Связанные темы. . ~ Эли ~