我的Android应用程序中有以下依赖项。在Dagger 2中做到这一点的最佳方法是什么?
Activity A ---- Adapter A and Adapter B and SharedPreferences
Activity B ---- Adapter B and SharedPreferences
Activity C ---- Adapter C and SharedPreferences
我是否必须为每个活动制作一个独特的组件?是否必须有三个独立的组件?
答案 0 :(得分:8)
在Android应用中,Dagger 2中的组件和模块的作用存在一些混淆。
组件用于将类似的生命周期组合在一起。
模块可以按功能线组织并进行测试(根据official instructions for testing)。
其中一些最好的例子是Google Android Architecture Blueprints Github repo。如果您检查那里的源代码,您可以看到有一个应用程序范围的组件(具有整个应用程序持续时间的生命周期),然后将活动和片段的活动范围组件分离为对应于给定功能的项目。当然,活动范围的组件的生命周期与其各自的活动相对应。
让我们转到您自己的特定用例。虽然一个活动范围的组件可以为活动A,B和C注入所有依赖关系,但对于问题中的简单示例可能是可接受的,如果需求发生变化且活动A突然需要新的依赖关系,情况将很快变得更加复杂。一个复杂的对象图。然后,您必须为新依赖项创建一个新模块,该模块仅对组件中三个注入站点之一有用。反过来,如果您使用模拟组件来测试活动B和活动C,这将使测试更加困难。
因此,我认为从一开始就最好每个活动维护一个组件。活动范围的组件便宜且易于维护,因此谨慎行事并不是每个活动都有一个活动范围的组件。
对于您指定的示例,我将创建一个应用程序范围的组件:
@Component( modules = { SharedPreferencesModule.class } )
@PerApp
interface AppComponent {
SharedPreferences sharedPreferences(Application app);
}
您可以让Activity组件成为app组件的依赖组件。这样他们就不必关心SharedPreferences
,因为它绑定在app-component中并暴露给dependents:
@Component( dependencies = { AppComponent.class }, modules = { AdapterAModule.class } )
@PerActivityA
interface ActivityAComponent {
}
请注意,这是dagger.android
包使用@ContributesAndroidInjector
鼓励的风格:
@PerActivityA
@ContributesAndroidInjector(modules = {ActivityAModule.class})
abstract YourActivity contributeYourActivityInjector();