匕首2子组件与组件依赖关系

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

在什么情况下使用 组件依赖关系而不是 子组件依赖性子组件依赖性是有益的? 为什么?

53973 次浏览

根据 文件:

Component Dependency只允许您通过组件依赖关系访问作为提供方法公开的绑定,也就是说,您只能访问在父 Component中声明的类型。

SubComponent声明 完整的绑定图时,SubComponent允许您从它的父级访问该绑定图,也就是说,您可以访问在其 Module中声明的所有对象。

比方说,您有一个包含所有 Android相关内容(LocationServiceResourcesSharedPreference等)的 ApplicationComponent。您还希望使用 DataComponent来管理持久性事务,同时使用 WebService来处理 API。你在 DataComponent中唯一缺少的是 Application Context,它位于 ApplicationComponent中。从 DataComponent获得 Android0的最简单方法是依赖于 ApplicationComponent。您需要确保在 ApplicationComponent中显式声明了 Android0,因为您只能访问已声明的内容。在这种情况下,不需要手工操作,这意味着您不需要在父 Android6中指定 Android5并显式地将子模块添加到父模块,比如:

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

现在考虑这种情况,您想要注入 WebServiceDataComponentLocationServiceApplicationComponent到您的 Fragment绑定使用上述 @Submodule plus功能。这里最酷的事情是,您绑定到的组件(ApplicationComponent)需要 DataComponent0公开 WebServiceLocationService,因为您可以立即访问整个图。

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

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


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

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

每当组件/子组件声明 ModuleB被初始化时,Dagger 将负责将 SomeClassA1的实例作为参数传递给 ModuleB上的 provideSomeClassB1()方法。我们需要指导匕首如何完成依赖。这可以通过使用 组件依赖性子成分来完成。

组件依赖性

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

  • 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可以有零个、一个或多个通过 组件依赖关系声明的“父”组件

下面是一个代码示例,带有屏幕快照,可以更好地理解 Component 和 SubComponent:

组成部分: enter image description here

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

子成分:

enter image description here

  1. AppComponent 包含子组件或子组件。
  2. 将 AppComponent 初始化为 App 类。
  3. 子组件不知道他的 ParentComponent,它只是通过包含模块来提供它自己的依赖关系。
  4. 在 HomeActivity 中,我通过使用它的父组件注入子组件。

图示: enter image description here

资料来源: 链接