具有多个接口实现的 Dagger Hilt

Dagger Hilt with multiple implementations of an interface

使用 Dagger2 可以很容易地显式创建组件并列出它们的依赖项。但是我似乎无法找到一种方法来提供一个接口的不同实现来让我们说一个片段。

例如,我的应用程序有两种生产模式:付费和免费。 我有一个付费 Activity 和一个免费 Activity,两者都以完全相同的仪表板片段开始,并带有一个分析 class。对于付费,我提供了一个 PaidAnalytics 实现,对于免费,我提供了一个 FreeAnalytics 实现。

使用 Dagger2,只需在 Activity 的组件(或子组件)中列出付费或免费模块即可轻松实现。

@Module
abstract class FreeActivityModule {

    @ContributesAndroidInjector(
        modules = [
            FreeAnalyticsModule::class,
            DashboardFragmentModule::class
        ]
    )
    abstract fun injectFreeActivity(): FreeActivity

}

@Module
abstract class PaidActivityModule {

    @ContributesAndroidInjector(
        modules = [
            PaidAnalyticsModule::class,
            DashboardFragmentModule::class
        ]
    )
    abstract fun injectPaidActivity(): PaidActivity

}

@Module
abstract class DashboardFragmentModule {

    @ContributesAndroidInjector
    abstract fun injectDashboardFragment(): DashboardFragment

}

class DashboardFragment : Fragment() {

    ...

    @Inject
    lateinit var analytics: Analytics

    ...

}

对于 Dagger Hilt,我找不到执行此操作的方法。

我认为我们可以利用 Hilt 的限定符功能来解决这个多重绑定问题。 这是我找到的一些资源:https://developer.android.com/codelabs/android-hilt#8 我引用:

To tell Hilt how to provide different implementations (multiple bindings) of the same type, you can use qualifiers.

我认为这是 Hilt 区分同一接口的不同实现的一种方式。

要设置您的 Hilt 模块:

@Qualifier
annotation class PaidModule

@Qualifier
annotation class FreeModule

@InstallIn(ActivityComponent::class)
@Module
abstract class PaidActivityModule {

    @ActivityScoped
    @Binds
    @PaidModule
    abstract fun bindPaidModule(impl: PaidActivity): YourInterface
}

@InstallIn(ActivityComponent::class)
@Module
abstract class FreeActivityModule {

    @ActivityScoped
    @Binds
    @FreeModule
    abstract fun bindFreeModule(impl: FreeActivity): YourInterface
}

注入:

@FreeModule
@Inject
lateinit var freeActivity: YourInterface

@PaidModule
@Inject
lateinit var paidActivity: YourInterface

在我的用例中,使用 Dagger 无法在运行时替换依赖项。

在其中一个 Google Hilt 会话期间,他们建议在 Provides 方法中使用 if else 语句:https://youtu.be/i27aNF-kYR4?t=3355(这是我希望避免的)。

上面的回答没有理解我的问题,因为它们是编译时限定的依赖项,我做不到。因为我的片段永远不知道它被使用的地方而且我不想只是复制代码。

这是一个示例,您可以在其中准确地看到我在做什么,而 Hilt 的设计是无法实现的:https://github.com/dmytroKarataiev/daggerAndroidvsHiltRuntimeDependencies