【发布时间】:2015-06-17 16:32:51
【问题描述】:
Dagger 1 的 plus() 方法是我在以前的应用程序中经常使用的方法,因此我了解您可能希望拥有一个对父图绑定具有完全访问权限的子组件的情况。
在什么情况下使用组件依赖而不是子组件依赖会有好处,为什么?
【问题讨论】:
Dagger 1 的 plus() 方法是我在以前的应用程序中经常使用的方法,因此我了解您可能希望拥有一个对父图绑定具有完全访问权限的子组件的情况。
在什么情况下使用组件依赖而不是子组件依赖会有好处,为什么?
【问题讨论】:
组件依赖 - 当你想保持两个组件独立时使用它。
子组件 - 当您想保持两个组件耦合时使用它。
我将使用下面的例子来解释组件依赖和子组件。该示例值得注意的几点是:
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() 方法。我们需要指示 Dagger 如何实现依赖。这可以通过使用组件依赖或子组件来完成。
请注意以下组件依赖示例中的以下几点:
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 已经通过接口方法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);
}
}
【讨论】:
SomeClassB1 依赖于 SomeClassA1。ComponentA 必须明确定义依赖关系。" ==> 你的意思是“ComponentB 必须明确定义依赖”?
SomeClassB1 依赖于SomeClassA1。ComponentA 不需要明确定义依赖关系。”你的意思是“ComponentB 不需要明确定义依赖关系。”
Component Dependency 使您只能访问通过组件依赖项作为配置方法公开的绑定,即您只能访问在父 Component 中声明的类型。
SubComponent 让您可以在声明时从其父级访问 整个 绑定图,即您可以访问在其 Modules 中声明的所有对象。
假设您有一个ApplicationComponent,其中包含所有与Android 相关的内容(LocationService、Resources、SharedPreference 等)。您还希望拥有您的DataComponent 来管理持久性事物以及WebService 来处理API。 DataComponent 中唯一缺少的是 Application Context,它位于 ApplicationComponent 中。从DataComponent 获取Context 的最简单方法是依赖ApplicationComponent。您需要确保在ApplicationComponent 中明确声明了Context,因为您只能访问已声明的内容。在这种情况下,无需手动操作,这意味着您无需在父级 Component 中指定 Submodules 并将子模块显式添加到父模块中,例如:
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
现在考虑您想将WebService 从DataComponent 和LocationService 从ApplicationComponent 注入到您的Fragment 的情况,该@Submodule 使用上面的plus 功能绑定。这里很酷的是,您绑定到 (ApplicationComponent) 的组件确实不需要 需要公开 WebService 或 LocationService,因为您可以立即访问整个图表。 p>
【讨论】:
@Submodule的接口。是不是笔误?
classes作为例子,多用图片来说明确切的点会有所帮助。
下面是代码示例和截图,可以让你更了解组件和子组件:
子组件:
来源:link
【讨论】:
直到现在我还没有完全意识到的另一件事是:
@Subcomponent 实例只有一个父组件(尽管不同的组件可以实例化相同的 @Subcomponent 并成为该实例的父组件)@Component 可能有零个、一个或多个通过component dependencies 声明的“父”组件
【讨论】: