Dagger 2 子组件与组件依赖关系
Dagger 2 subcomponents vs component dependencies
Dagger 1 的 plus()
方法是我在以前的应用程序中经常使用的方法,所以我理解您可能希望拥有一个可以完全访问父图绑定的子组件的情况。
在什么情况下使用组件依赖性而不是子组件依赖性会有好处,为什么?
根据 documentation:
Component Dependency
使您只能访问通过组件依赖项公开为提供方法的绑定,即您只能访问在父 Component
.
中声明的类型
SubComponent
允许您在声明时从其父级访问 整个 绑定图,即您可以访问其 [= 中声明的所有对象14=]s.
假设您有一个 ApplicationComponent
包含所有 Android
相关内容(LocationService
、Resources
、SharedPreference
等)。您还希望使用 DataComponent
来管理持久性以及 WebService
来处理 API。 DataComponent
中唯一缺少的是位于 ApplicationComponent
中的 Application Context
。从 DataComponent
获取 Context
的最简单方法是依赖 ApplicationComponent
。您需要确保在 ApplicationComponent
中明确声明了 Context
,因为您只能访问已声明的内容。在这种情况下,没有手动工作,这意味着您不需要在父 Component
中指定 Submodules
并将子模块显式添加到父模块,例如:
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
现在考虑这样一种情况,您想要将 DataComponent
中的 WebService
和 ApplicationComponent
中的 LocationService
注入到您的 Fragment
中,它使用 @Submodule
plus
上面的特征。这里很酷的是你绑定到的组件 (ApplicationComponent
) not 不需要公开 WebService
也不需要 LocationService
因为你有访问权限立即查看整个图表。
组件依赖 - 当你想保持两个组件独立时使用它。
子组件 - 当您想保持两个组件耦合时使用此选项。
我将使用下面的示例来解释 组件依赖项 和 子组件。该示例值得注意的一些要点是:
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;
}
}
Dagger 会负责将 SomeClassA1
的实例作为参数传递给 ModuleB
上的 provideSomeClassB1()
方法,只要 Component/Subcomponent 声明 ModuleB
被初始化.我们需要指示 Dagger 如何实现依赖。这可以通过使用 Component dependency 或 Subcomponent.
来完成
组件依赖
请注意以下组件依赖示例中的以下几点:
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
可能有零个、一个或多个 "parent" 组件通过 component dependencies 声明
为了更好地理解组件和子组件,这里是带有屏幕截图的代码示例:
分量:
- AppComponent 包含两个声明。
- AppComponent 初始化为 App class。
- HomeActivityComponent 依赖于 AppComponent。
- 在 DaggerHomeActivityComponent 初始化的 HomeActivity 中,我将 AppComponent 对象作为一个组合。
子组件:
- AppComponent 包含一个或多个 SubComponent。
- AppComponent 初始化为 App class。
- SubComponent 不知道他的 ParentComponent。仅通过包含 Module.
来提供自己的依赖项
- 在 HomeActivity 中,我使用其父组件注入子组件。
及示意图:
来源:link
Dagger 1 的 plus()
方法是我在以前的应用程序中经常使用的方法,所以我理解您可能希望拥有一个可以完全访问父图绑定的子组件的情况。
在什么情况下使用组件依赖性而不是子组件依赖性会有好处,为什么?
根据 documentation:
Component Dependency
使您只能访问通过组件依赖项公开为提供方法的绑定,即您只能访问在父 Component
.
SubComponent
允许您在声明时从其父级访问 整个 绑定图,即您可以访问其 [= 中声明的所有对象14=]s.
假设您有一个 ApplicationComponent
包含所有 Android
相关内容(LocationService
、Resources
、SharedPreference
等)。您还希望使用 DataComponent
来管理持久性以及 WebService
来处理 API。 DataComponent
中唯一缺少的是位于 ApplicationComponent
中的 Application Context
。从 DataComponent
获取 Context
的最简单方法是依赖 ApplicationComponent
。您需要确保在 ApplicationComponent
中明确声明了 Context
,因为您只能访问已声明的内容。在这种情况下,没有手动工作,这意味着您不需要在父 Component
中指定 Submodules
并将子模块显式添加到父模块,例如:
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
现在考虑这样一种情况,您想要将 DataComponent
中的 WebService
和 ApplicationComponent
中的 LocationService
注入到您的 Fragment
中,它使用 @Submodule
plus
上面的特征。这里很酷的是你绑定到的组件 (ApplicationComponent
) not 不需要公开 WebService
也不需要 LocationService
因为你有访问权限立即查看整个图表。
组件依赖 - 当你想保持两个组件独立时使用它。
子组件 - 当您想保持两个组件耦合时使用此选项。
我将使用下面的示例来解释 组件依赖项 和 子组件。该示例值得注意的一些要点是:
SomeClassA1
可以在没有任何依赖的情况下创建。ModuleA
通过provideSomeClassA1()
方法提供SomeClassA1
的实例。
没有 SomeClassB1
。只有当SomeClassA1
的实例作为参数传递给provideSomeClassB1()
方法时,ModuleB
才能提供SomeClassB1
的实例。
SomeClassA1
就无法创建 @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()
方法,只要 Component/Subcomponent 声明 ModuleB
被初始化.我们需要指示 Dagger 如何实现依赖。这可以通过使用 Component dependency 或 Subcomponent.
组件依赖
请注意以下组件依赖示例中的以下几点:
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
可能有零个、一个或多个 "parent" 组件通过 component dependencies 声明
为了更好地理解组件和子组件,这里是带有屏幕截图的代码示例:
分量:
- AppComponent 包含两个声明。
- AppComponent 初始化为 App class。
- HomeActivityComponent 依赖于 AppComponent。
- 在 DaggerHomeActivityComponent 初始化的 HomeActivity 中,我将 AppComponent 对象作为一个组合。
子组件:
- AppComponent 包含一个或多个 SubComponent。
- AppComponent 初始化为 App class。
- SubComponent 不知道他的 ParentComponent。仅通过包含 Module. 来提供自己的依赖项
- 在 HomeActivity 中,我使用其父组件注入子组件。
及示意图:
来源:link