143

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

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

4

4 回答 4

245

组件依赖关系 - 当您想保持两个组件独立时使用此选项。

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


我将使用下面的示例来解释Component dependenciesSubcomponents。关于该示例的一些值得注意的点是:

  • SomeClassA1可以在没有任何依赖的情况下创建。通过方法ModuleA提供和实例。SomeClassA1provideSomeClassA1()
  • SomeClassB1没有SomeClassA1. 只有当一个实例作为参数传递给方法ModuleB时,才能提供一个实例。SomeClassB1SomeClassA1provideSomeClassB1()
@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()方法。我们需要指示 Dagger 如何实现依赖。这可以通过使用Component 依赖Subcomponent来完成。ModuleBModuleB

组件依赖

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

  • 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注释。
  • ComponentAModuleB通过接口方法声明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);
    }
}
于 2015-05-09T01:55:36.713 回答
47

根据文档

Component Dependency使您只能访问通过组件依赖项作为提供方法公开的绑定,即您只能访问在 parent 中声明的类型Component

SubComponent在声明绑定图时,您可以从其父级访问整个Module绑定图,即您可以访问在其s 中声明的所有对象。

比方说,您有一个ApplicationComponent包含所有Android相关内容(LocationService、、、ResourcesSharedPreference)的内容。您还希望拥有DataComponent管理持久性事物的位置以及WebService处理 API。您唯一缺少的DataComponentApplication Context位于ApplicationComponent. 获取Contextfrom的最简单方法DataComponent是依赖ApplicationComponent. 你需要确保你有一个Context明确的声明,ApplicationComponent因为你只能访问声明的东西。在这种情况下,没有手动工作,这意味着您不需要Submodules在父模块中指定Component并将子模块显式添加到父模块,例如:

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

现在考虑一下你想使用上面的功能从哪个绑定中WebService注入和注入DataComponent的情况。这里很酷的是,您绑定到 ( )的组件不需要公开,也因为您可以立即访问整个图形。LocationServiceApplicationComponentFragment@Submodule plusApplicationComponentWebServiceLocationService

于 2015-05-05T19:59:35.323 回答
18

以下是带有屏幕截图的代码示例,用于更多地了解 Component 和 SubComponent:

零件: 在此处输入图像描述

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

子组件:

在此处输入图像描述

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

和示意图: 在此处输入图像描述

来源:链接

于 2018-07-24T18:46:14.757 回答
1

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

  • 一个@Subcomponent实例只有一个父组件(尽管不同的组件可以实例化相同@Subcomponent并成为该实例的父组件)
  • A@Component可能有零个、一个或多个通过组件依赖项声明的“父”组件
于 2018-04-05T11:43:31.460 回答