Dagger 2 子组件与组件依赖关系

Dagger 2 subcomponents vs component dependencies

Dagger 1 的 plus() 方法是我在以前的应用程序中经常使用的方法,所以我理解您可能希望拥有一个可以完全访问父图绑定的子组件的情况。

在什么情况下使用组件依赖性而不是子组件依赖性会有好处,为什么?

根据 documentation:

Component Dependency 使您只能访问通过组件依赖项公开为提供方法的绑定,即您只能访问在父 Component.

中声明的类型

SubComponent 允许您在声明时从其父级访问 整个 绑定图,即您可以访问其 [= 中声明的所有对象14=]s.

假设您有一个 ApplicationComponent 包含所有 Android 相关内容(LocationServiceResourcesSharedPreference 等)。您还希望使用 DataComponent 来管理持久性以及 WebService 来处理 API。 DataComponent 中唯一缺少的是位于 ApplicationComponent 中的 Application Context。从 DataComponent 获取 Context 的最简单方法是依赖 ApplicationComponent。您需要确保在 ApplicationComponent 中明确声明了 Context,因为您只能访问已声明的内容。在这种情况下,没有手动工作,这意味着您不需要在父 Component 中指定 Submodules 并将子模块显式添加到父模块,例如:

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

现在考虑这样一种情况,您想要将 DataComponent 中的 WebServiceApplicationComponent 中的 LocationService 注入到您的 Fragment 中,它使用 @Submodule plus 上面的特征。这里很酷的是你绑定到的组件 (ApplicationComponent) not 不需要公开 WebService 也不需要 LocationService 因为你有访问权限立即查看整个图表。

组件依赖 - 当你想保持两个组件独立时使用它。

子组件 - 当您想保持两个组件耦合时使用此选项。


我将使用下面的示例来解释 组件依赖项子组件。该示例值得注意的一些要点是:

  • SomeClassA1 可以在没有任何依赖的情况下创建。 ModuleA 通过 provideSomeClassA1() 方法提供 SomeClassA1 的实例。
  • 没有 SomeClassA1 就无法创建
  • SomeClassB1。只有当 SomeClassA1 的实例作为参数传递给 provideSomeClassB1() 方法时,ModuleB 才能提供 SomeClassB1 的实例。
@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 的实例作为参数传递给 ModuleB 上的 provideSomeClassB1() 方法,只要 Component/Subcomponent 声明 ModuleB 被初始化.我们需要指示 Dagger 如何实现依赖。这可以通过使用 Component dependencySubcomponent.

来完成

组件依赖

请注意以下组件依赖示例中的以下几点:

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

子组件

注意子组件示例中的以下几点:

  • 由于ComponentB没有定义对ModuleA的依赖,所以不能独立生存。它变得依赖于将提供 ModuleA 的组件。因此它有一个 @Subcomponent 注释。
  • ComponentA 已通过接口方法 componentB() 声明了 ModuleB。这使得两个组件耦合。实际上,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);
    }
}

直到现在我还没有完全意识到的另一件事是:

  • 一个@Subcomponent实例只有一个父组件(尽管不同的组件可以实例化同一个@Subcomponent并成为该实例的父组件)
  • 一个 @Component 可能有零个、一个或多个 "parent" 组件通过 component dependencies
  • 声明

为了更好地理解组件和子组件,这里是带有屏幕截图的代码示例:

分量:

  1. AppComponent 包含两个声明。
  2. AppComponent 初始化为 App class。
  3. HomeActivityComponent 依赖于 AppComponent。
  4. 在 DaggerHomeActivityComponent 初始化的 HomeActivity 中,我将 AppComponent 对象作为一个组合。

子组件:

  1. AppComponent 包含一个或多个 SubComponent。
  2. AppComponent 初始化为 App class。
  3. SubComponent 不知道他的 ParentComponent。仅通过包含 Module.
  4. 来提供自己的依赖项
  5. 在 HomeActivity 中,我使用其父组件注入子组件。

及示意图:

来源:link