Один экземпляр для разных областей применения с кинжалом 2 - PullRequest
1 голос
/ 07 ноября 2019

Проблема

Я создаю приложение с динамической функцией.

Чтобы предоставить все зависимости для основного модуля и функционального модуля, я использую кинжал 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
}

Ожидаемый результат

Интерфейсы TestC и TestA вводятся в MainActivity

Интерфейсы TestB и TestA являютсявставлено в TestBroadcastReceiver

Как и ожидалось, экземпляр реализации TestA уникален, но для реализации TestB это не так. Так как TestC зависит от TestB, то, что введено в TestC, отличается от того, которое введено в TestBroadcastReceiver с аннотацией @TestScope.

Итак, запустив пример проекта, который вы можете найти здесь Я получаю следующие выходные данные журнала

Экземпляры, введенные в MainActivity

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

Экземпляры, введенные в TestBroadcastReceiver

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

Я хотел бы использовать один и тот же экземпляр TestB в обоих модулях.

Есть предложения? Заранее спасибо!

...