使用 Fragment Factory 时如何将 dagger 依赖关系与 fragment 联系起来?

How to scope dagger dependencies with fragments when using Fragment Factory?

在不使用 FragmentFactory 的情况下,Fragment 内的范围依赖关系是直截了当的。只需为您的片段创建一个 Subcomponent 并在 onAttach().

中创建 Fragment 的子组件

但是当使用 FragmentFactory 时,您不再通过子组件注入依赖项,而是在 Fragment 的构造函数中传递。

我想知道我是否仍然可以使用 Dagger 声明一个只应在片段的生命周期内持续的依赖项。我目前想不出一种方法来实现这一点。

因此,我没有将我的依赖项绑定到某个范围,而是声明了任何范围的依赖项,或者只是对它们使用 @Reusable

另外,由于片段是通过FragmentFactory创建的,因此创建的Fragments不存在于DI图中。

我们如何才能正确地将依赖范围限定为片段,并在使用 FragmentFactory 时能够将片段添加到 DI 图中?

您可以通过让 Subcomponent 负责创建您的 Fragment 来实现此目的。 Fragment 应与此 Subcomponent 具有相同的范围。

@Subcomponent(modules = [/* ... */])
@FragmentScope
interface FooSubcomponent {

    fun fooFragment(): FooFragment

    @Subcomponent.Factory
    interface Factory {
        fun create(): FooSubcomponent
    }
}

在解决任何循环依赖问题后,此 Subcomponent 的行为与您使用 @BindsInstanceonAttach() 中显式创建子组件相同,只是您可以(并且must) 现在在 FooFragment.

上使用构造函数注入

为了在您的主要组件(或父子组件)中提供 FooFragment,您需要将此 Subcomponent 安装到模块中。

@Module(subcomponents = [FooSubcomponent::class])
object MyModule {
    @Provides
    @IntoMap
    @FragmentKey(FooFragment::class)
    fun provideFooFragment(factory: FooSubcomponent.Factory): Fragment {
        return factory.create().fooFragment()
    }
}

一些注意事项:

  1. 你描述的场景(FooFragment依赖于一些class而依赖于FooFragment)是循环依赖的定义。你需要在这个循环的某个时刻注入一个 LazyProvider,否则 Dagger 会在编译时抛出错误。

  2. 如果将其分成两步,首先提供 FooFragment 然后将其绑定到您的地图中,子组件将从其父组件看到 @Provides 方法。如果您不小心,这可能会导致 WhosebugError