带有匕首2的不同作用域的单个实例

问题

我正在构建具有动态功能的应用程序。

要提供我使用的匕首2对主模块和功能模块的所有依赖关系。功能部件取决于主部件,因此,功能部件的作用域与主部件作用域不同(在这种情况下为@Singleton

注入到主模块中的一个接口在功能模块上实现,并通过反射在主模块中提供。该实现还用于功能模块中。

我的问题是主模块中提供的实例不同于功能模块中的实例(由于作用域),但我只想让一个带有匕首的实例

代码

这里有一些代码,您可以在github

中找到整个示例项目。

主模块的匕首配置:

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
}

功能模块的匕首配置:

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
}

预期结果

接口TestCTestA被注入Mainactivity

接口TestBTestA被注入TestBroadcastReceiver

不出所料,TestA实现的实例是唯一的,但是TestB的实现不是那样。由于TestC取决于TestB,因此注入TestC的对象与注入带有TestBroadcastReceiver注释的@TestScope的对象不同。

因此,运行示例项目可以找到here,我将获得以下日志输出

Mainactivity

中注入的实例
D/TestB: instance 40525431
D/TestC: instance 119319268
D/TestA: instance 60713805

TestBroadcastReceiver

中注入的实例
D/TestB: instance 219966227
D/TestA: instance 60713805

我想在两个模块中共享TestB的相同实例。

有什么建议吗? 预先感谢!

q4023586 回答:带有匕首2的不同作用域的单个实例

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

,

我在DaggerTestDependencyComponent中构建Injector的两个实例,而在实现TestC时构建另一个实例

我找到的解决方案如下:

  • 创建一个对象,可以在其中实例化将与TestDependencyComponentInjector共享的TestCImplementation

    object FeatureInjector {
    
        val testDependencyComponent: TestDependencyComponent by lazy {
            DaggerTestDependencyComponent.builder()
                .testComponent(com.example.daggertest.dagger.Injector.testComponent)
                .build()
        }
    }
    
  • 现在,我像这样修改了功能Injector

    object Injector {
    
        lateinit var testDependencyComponent: TestDependencyComponent
    
        @JvmStatic
        internal fun getTestDependencyComponent(): TestDependencyComponent {
            if (!::testDependencyComponent.isInitialized) {
                testDependencyComponent = FeatureInjector.testDependencyComponent
            }
            return testDependencyComponent
        }
    }
    
  • TestCImplementation如下:

    class TestCImplementation @Inject constructor(
        private val testB: TestB
    ) : TestC {
        override fun testCFun() {
            testB.testBFun()
            Log.d("TestC","instance ${System.identityHashCode(this)}")
        }
    
        companion object Provider : TestC.Provider {
            override fun get(testComponent: TestComponent): TestC {
                return FeatureInjector.testDependencyComponent.testC()
            }
        }
    }
    

现在运行代码,我得到了TestB的相同实例

本文链接:https://www.f2er.com/3144271.html

大家都在问