Dagger 1 的plus()
方法是我在以前的应用程序中经常使用的方法,因此我了解您可能希望拥有一个可以完全访问父图绑定的子组件的情况。
在什么情况下使用组件依赖而不是子组件依赖会有好处,为什么?
组件依赖关系 - 当您想保持两个组件独立时使用此选项。
子组件 - 当您想保持两个组件耦合时使用它。
我将使用下面的示例来解释Component dependencies和Subcomponents。关于该示例的一些值得注意的点是:
SomeClassA1
可以在没有任何依赖的情况下创建。通过方法ModuleA
提供和实例。SomeClassA1
provideSomeClassA1()
SomeClassB1
没有SomeClassA1
. 只有当一个实例作为参数传递给方法ModuleB
时,才能提供一个实例。SomeClassB1
SomeClassA1
provideSomeClassB1()
@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来完成。ModuleB
ModuleB
请注意以下组件依赖示例中的以下几点:
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
已ModuleB
通过接口方法声明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);
}
}
根据文档:
Component Dependency
使您只能访问通过组件依赖项作为提供方法公开的绑定,即您只能访问在 parent 中声明的类型Component
。
SubComponent
在声明绑定图时,您可以从其父级访问整个Module
绑定图,即您可以访问在其s 中声明的所有对象。
比方说,您有一个ApplicationComponent
包含所有Android
相关内容(LocationService
、、、Resources
等SharedPreference
)的内容。您还希望拥有DataComponent
管理持久性事物的位置以及WebService
处理 API。您唯一缺少的DataComponent
是Application Context
位于ApplicationComponent
. 获取Context
from的最简单方法DataComponent
是依赖ApplicationComponent
. 你需要确保你有一个Context
明确的声明,ApplicationComponent
因为你只能访问声明的东西。在这种情况下,没有手动工作,这意味着您不需要Submodules
在父模块中指定Component
并将子模块显式添加到父模块,例如:
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
现在考虑一下你想使用上面的功能从哪个绑定中WebService
注入和注入DataComponent
的情况。这里很酷的是,您绑定到 ( )的组件不需要公开,也因为您可以立即访问整个图形。LocationService
ApplicationComponent
Fragment
@Submodule
plus
ApplicationComponent
WebService
LocationService
以下是带有屏幕截图的代码示例,用于更多地了解 Component 和 SubComponent:
子组件:
来源:链接
直到现在我还没有完全意识到的另一件事是:
@Subcomponent
实例只有一个父组件(尽管不同的组件可以实例化相同@Subcomponent
并成为该实例的父组件)@Component
可能有零个、一个或多个通过组件依赖项声明的“父”组件