Problem
I am building an app with a dynamic feature.
To provide all the dependencies to the main module and the feature module I am using dagger 2. The feature component is depending on the main component and because of that, the feature component is having a different scope than the main component scope (@Singleton
in that case)
One of the interface injected in the main module are implemented on the feature module and provided by reflection in the main module. The implementation is also used in the feature module.
The problem that I have is that the instance provided in the main module is different from the one in the feature module (because of the scopes) but I would like to have just one instance provided with dagger.
Code
Here some code and you can find the whole example project in github
Dagger configuration for the main module:
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 configuration for the feature module:
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
}
Expected result
The interfaces TestC
and TestA
are injected in the MainActivity
The interfaces TestB
and TestA
are injected in the TestBroadcastReceiver
As expected the instance of the TestA
implementation is unique but for the implementation of the TestB
is not that way. As TestC
depends on TestB
the one injected in TestC
is different from the one injected in the TestBroadcastReceiver
with the @TestScope
annotation.
So running the example project that you can find here I get the following log output
Instances injected in the MainActivity
D/TestB: instance 40525431
D/TestC: instance 119319268
D/TestA: instance 60713805
Instances injected in the TestBroadcastReceiver
D/TestB: instance 219966227
D/TestA: instance 60713805
I would like to share the same instance of TestB
in both modules.
Any suggestion? Thanks in advance!