我想使用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标记的方法。

最佳答案

在您的特定情况下,Dagger似乎找不到XPresenter的绑定;您有一个从@Binds XContract.PresenterXPresenter的语句,但是根据您对“ XPresenter实现本身”的随意提及,您可能似乎缺少以下语句:

@Binds
abstract XPresenter providesXPresenter(XPresenterImpl presenterImpl);


范围可以取决于相同的范围:@ActivityScope中的项目可以取决于@ActivityScope,而不能取决于@FragmentScope。如果尝试依赖@ActivityScope中的@FragmentScope对象(“范围扩大注入”),则Dagger将阻止它,并描述可以在其中找到注入的组件。

但是,您也可能会遇到@FragmentScope组件不能包含其他@FragmentScope组件的麻烦,考虑到@ContributesAndroidInjector必须创建一个采用该方法列出的作用域和模块的新子组件,因此这是一个问题。您需要调整范围注释的选择,例如创建和使用@ParentFragmentScope和@ChildFragmentScope。这也很重要,因为您的@ChildFragmentScope Fragment XFragment可以注入共享XFragment的子组件实例,AFragment的子组件实例,MainActivity的子组件实例或根@Singleton组件的生命周期的对象。

当然,您可能需要根据用例为它们命名,例如@FullScreenFragmentScope或@TabFragmentScope或@OptionalFlowFragmentScope;您还可以选择外部范围以保持@FragmentScope,内部范围选择为@SubFragmentScope等等,如果您已经具有可重复使用的模块,而它们已经使用@FragmentScope,则这可能特别有用。关键是,使用@FragmentScope的可重用模块尚不清楚是跟踪AFragment的生命周期还是XFragment的生命周期,因此您需要对此更加清楚。

07-24 09:50
查看更多