android - 带有 Dagger 2 的不同范围的单个实例

标签 android kotlin dependency-injection dagger-2 dynamic-feature-module

问题

我正在构建一个具有动态功能的应用。

为了提供对主模块和功能模块的所有依赖,我使用了 dagger 2。功能组件依赖于主组件,因此,功能组件的范围与主组件范围不同( @Singleton 在这种情况下)

在主模块中注入(inject)的接口(interface)之一是在功能模块上实现的,并通过主模块中的反射提供。该实现也用于功能模块。

我遇到的问题是主模块中提供的实例与功能模块中的实例不同(因为作用域),但我希望只有一个实例随 dagger 一起提供。

代码

这里有一些代码,您可以在 github 中找到整个示例项目

主模块的 Dagger 配置:

TestModule.kt

@Module
class TestModule {

    @Provides
    @Singleton
    fun provideTestA() : TestA = TestAImplementation()

    private var testCProvider: TestC?= null

    @Provides
    @Singleton
    fun provideTestC(testComponent: TestComponent) : TestC {
        if(testCProvider != null) return testCProvider as TestC

        val provider = Class.forName("com.example.feature.services.TestCImplementation\$Provider").kotlin.objectInstance as TestC.Provider
        return provider
            .get(testComponent)
            .also { testCProvider = it }
    }
}

TestComponent.kt

@Singleton
@Component(modules = [TestModule::class])
interface TestComponent {
    fun inject(activity: MainActivity)

    fun provideTestA() : TestA
}

功能模块的 Dagger 配置:

TestDependencyModule.kt

@Module
class TestDependencyModule {

    @Provides
    @TestScope
    fun provideTestB(): TestB = TestBImplementation()

    @Provides
    @TestScope
    fun provideTestC(testB: TestB): TestC = TestCImplementation(testB)
}

TestDependencyComponent.kt

@TestScope
@Component(
    modules = [TestDependencyModule::class],
    dependencies = [TestComponent::class]
)
interface TestDependencyComponent {
    fun inject(receiver: TestBroadcastReceiver)

    fun testC(): TestC
}

预期结果

接口(interface) TestCTestA被注入(inject) MainActivity

接口(interface) TestBTestA被注入(inject) TestBroadcastReceiver

正如预期的那样,TestA 的实例实现是唯一的,但对于 TestB 的实现不是那样的。作为TestC取决于 TestBTestC 中注入(inject)的那个与在 TestBroadcastReceiver 中注入(inject)的不同与 @TestScope注释。

运行示例项目,您可以找到here我得到以下日志输出

MainActivity 中注入(inject)的实例

D/TestB: instance 40525431
D/TestC: instance 119319268
D/TestA: instance 60713805

TestBroadcastReceiver 中注入(inject)的实例

D/TestB: instance 219966227
D/TestA: instance 60713805

我想分享 TestB 的同一个实例在两个模块中。

有什么建议吗? 提前致谢!

最佳答案

TestDependencyComponent 无法从 TestComponent 上的组件依赖项访问 TestC,因为 TestComponent 不会在其公共(public) API 上公开 TestC。如果添加 fun testC(): TestC在 TestComponent 上,我希望您在处理 TestDependencyComponent 时会收到重复绑定(bind)异常。从那里您需要确定提供 TestC 实例的正确方法。

关于android - 带有 Dagger 2 的不同范围的单个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58750363/

相关文章:

android - 在 Android 中创建通知应用程序?

kotlin - 我可以在没有相应 getter 的情况下对 Java setter 使用属性语法吗?

java - Spring依赖注入(inject)不起作用

Android Dagger 更新模块外的值

android - 在 Tab 主机 android 中打开子 Activity

Android RecyclerView Endless Scroll on load more, jumps to top

java - Android:运行多个 Activity

android - 我如何等待 Kotlin 协程中的其他事件?

android - 如何在 anko 中为按钮设置图标(可绘制)?

symfony - 从另一个包修改包配置