Dagger 1的plus()方法是我之前经常使用的,因此我了解您可能希望拥有完全访问父图绑定的子组件的情况。
在什么情况下使用组件依赖会比子组件依赖更有益,为什么?
组件依赖 - 当您想要保持两个组件独立时使用此选项。
子组件 - 当您想要将两个组件耦合在一起时使用此选项。
我将使用以下示例来解释组件依赖和子组件。 有关示例的一些值得注意的点是:
SomeClassA1可以在没有任何依赖关系的情况下创建。 ModuleA通过provideSomeClassA1()方法提供了SomeClassA1的实例。SomeClassB1无法在没有SomeClassA1的情况下创建。 只有在将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()方法,每当声明依赖ModuleB的Component/Subcomponent被初始化时。我们需要指示Dagger如何满足依赖关系。这可以通过使用组件依赖或子组件来实现。
请注意以下组件依赖示例中的几点:
ComponentB必须通过@Component注解上的dependencies方法定义依赖关系。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);
}
}
Component Dependency 通过组件依赖仅让您访问公开的提供方法绑定,即您只能访问在父 Component 中声明的类型。
SubComponent 在声明时具有访问其父级中整个绑定图的权限,即您可以访问其所有 Module 中声明的对象。
假设您有一个包含所有与 Android 相关的内容(例如 LocationService、Resources、SharedPreference 等)的 ApplicationComponent。您还想拥有 DataComponent,用于管理持久性事务以及用于处理 API 的 WebService。在 DataComponent 中唯一缺少的是位于 ApplicationComponent 中的 ApplicationContext。从 DataComponent 获取 Context 的最简单方法是依赖于 ApplicationComponent。您需要确保在 ApplicationComponent 中明确定义了一个 Context,因为您只能访问已声明的内容。在这种情况下,没有手动工作,也就是说,您不需要在父 Component 中指定 Submodules,也不需要将您的子模块显式添加到父模块中,例如:MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
现在考虑这样一种情况:您想从DataComponent注入WebService,并且从ApplicationComponent注入LocationService到使用上述@Submodule plus功能绑定的Fragment中。这里很酷的一点是,您要绑定到的组件(ApplicationComponent)不需要公开WebService和LocationService,因为您立即可以访问整个图。
@Submodule的接口。这是一个打字错误吗? - Islam Salah这是一个带有截图的示例代码,以更好地理解组件和子组件:
子组件(SubComponent):
来源: 链接
直到现在我才意识到的另一件事是:
@Subcomponent 实例只有一个父组件(尽管不同的组件可以实例化相同的 @Subcomponent 并成为该实例的父级)@Component 可以通过 组件依赖 声明零个、一个或多个“父”组件
SomeClassB1依赖于SomeClassA1。ComponentA必须明确定义依赖关系。" ==> 你是不是想说 "ComponentB必须明确定义依赖关系"? - TarSomeClassB1依赖于SomeClassA1。ComponentA不需要显式地定义依赖关系。”你想说的是"ComponentB不需要显式地定义依赖关系。" - Sebas LG