我想使用Dagger为带有子片段(X ... Z)FragModule的AFragment组成模块。
从ActivityBindingModule开始,我定义示例活动的依赖模块
/* ActivityBindingModule.java */
@Module
public abstract class ActivityBindingModule{
@NonNull
@ActivityScoped
@ContributesAndroidInjector(modules = {
AFragModule.class,
BFragModule.class
// ... fragment modules
})
abstract MainActivity mainActivity();
}
在AFragModule中,我定义了其依赖于子片段的模块。
/* AFragModule.java */
@Module
public abstract class AFragModule{
@NonNull
@FragmentScoped
@ContributesAndroidInjector(modules = {
XFragModule.class,
YFragModule.class
// ... child fragment modules
})
abstract AFragment providesFragment();
}
在(X ... Z)FragModule中,我定义了其依赖对象的提供程序方法。
/* XFragModule.java */
@Module
public abstract class XFragModule{
@FragmentScoped
@ContributesAndroidInjector
abstract XFragment providesFragment();
@ActivityScoped
@Binds
abstract XContract.Presenter providesPresenter(XPresenter presenter);
}
我希望将(X ... Z)FragModule模块的作用域限定在AFragModule中。而且(X ... Z)FragModules的演示者还可以在同一范围内进行演示者之间的通信。
XPresenter实现本身使用带有@Singleton参数(例如数据源)的构造函数注入器
在上述范围内,我收到以下错误:
Cause: binding is not resolved for XContract.Presenter: ProvisionBinding{contributionType=UNIQUE, key=XContract.Presenter, bindingElement=Optional[providesPresenter(XPresenter)], contributingModule=Optional[XFragModule], kind=DELEGATE, nullableType=Optional.empty, wrappedMapKeyAnnotation=Optional.empty, provisionDependencies=[DependencyRequest{kind=INSTANCE, key=XPresenter, requestElement=Optional[presenter], isNullable=false}], injectionSites=[], unresolved=Optional.empty, scope=Optional[@ActivityScoped]}
编辑: 我也想检查一下我对范围的理解: 我“认为”我了解以下内容
@Singleton> @ActivityScope> @FragmentScope
范围不能依赖相同或较小的范围 例如@ActivityScope不能依赖@ActivityScope或@FragmentScope
范围可以取决于任何更大的范围。 例如@FragmentScope可以依赖于@ Singleton,@ ActivityScope标记的方法。
答案 0 :(得分:1)
在您的特定情况下,Dagger似乎找不到XPresenter的绑定;您有一个从@Binds XContract.Presenter
到XPresenter
的语句,但是基于您对“ XPresenter实现本身”的随意提及,您似乎可能缺少以下语句:
@Binds
abstract XPresenter providesXPresenter(XPresenterImpl presenterImpl);
范围可以取决于相同的范围:@ActivityScope中的项目可以取决于@ActivityScope,而不能取决于@FragmentScope。如果您尝试依赖@ActivityScope中的@FragmentScope对象(“范围扩大注入”),则Dagger将阻止它,并描述可以在其中找到注入的组件。
但是,您也可能会遇到@FragmentScope组件不能包含其他@FragmentScope组件的麻烦,鉴于@ContributesAndroidInjector必须创建一个采用该方法列出的作用域和模块的新子组件,因此这是一个问题。您需要调整范围注释的选择,例如创建并使用@ParentFragmentScope和@ChildFragmentScope 。这也很重要,因为您的@ChildFragmentScope片段 XFragment 可以注入共享XFragment的子组件实例,AFragment的子组件实例,MainActivity的子组件实例或根@Singleton组件的生命周期的对象。
当然,您可能需要根据使用情况为它们命名,例如@FullScreenFragmentScope或@TabFragmentScope或@OptionalFlowFragmentScope;您还可以选择外部范围以保留@FragmentScope,内部范围选择为@SubFragmentScope等等,如果您已经具有可重复使用的模块,而它们已经使用@FragmentScope,则这可能特别有用。关键是,使用@FragmentScope的可重用模块尚不清楚是跟踪AFragment的生命周期还是XFragment的生命周期,因此您需要对此更加清楚。