Как использовать Koin в нескольких модулях? - PullRequest
2 голосов
/ 24 мая 2019

В моем проекте Android есть два модуля: модуль приложения и модуль lib.

Оба эти двух модуля нуждаются в Koin для D.I., поэтому я вызываю startKoin в MyApplication классе в модуле приложения и IninKointContentProvider в модуле lib, как показано ниже.

// app module
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin(this, modules1)
    }
}

// lib module
class InitKoinContentProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        startKoin(context.applicationContext, modules2)
        return true
    }
}

Затем приложение упало и показало это сообщение

Caused by: org.koin.error.BeanOverrideException: Try to override definition with Single [class='android.content.Context'], but override is not allowed. Use 'override' option in your definition or module.

Полагаю, startKoin можно вызвать только один раз.

Решение, которое я нашел, заключается в объединении двух модулей koin с последующим вызовом startKoin в MyApplication, но мне это не нравится. Модуль Lib может быть импортирован другим Android-проектом, который не использует koin, в этом случае, я думаю, что лучше вызывать startKoin в InitKoinContentProvider.

Любое решение для этой проблемы ?? Спасибо!

Ответы [ 3 ]

1 голос
/ 24 мая 2019

В ваших библиотечных модулях используйте loadKoinModules() для загрузки специфичных для модуля модулей koin. Docs .

До этого вам нужно запустить startKoin(), поэтому порядок инициализации с поставщиками контента может быть немного сложным.

0 голосов
/ 29 мая 2019

Я нашел лучшее решение, вдохновленное ответом @ laalto, спасибо!

Обновите до koin 2.0, затем используйте KoinApplication и настроенный KoinComponent для создания изолированного контекста koin, он может позволить модулю lib использовать koin без какого-либо инициализирующего вызова через модуль приложения, все еще запускать koin в ContentProvider. Весь код может понравиться ниже.

// app module
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin {
            androidContext(this@MyApplication)
            modules(module{
                viewModel { MainViewModel() }
            })
        }
    }
}

class MainActivity: AppCompactActivity() {
    private val viewModel: MainViewModel by viewModel()
}



// lib module
internal object MyKoinContext {
    lateinit var koinApplication: KoinApplication
}

interface MyKoinComponent : KoinComponent {
    override fun getKoin(): Koin {
        return MyKoinContext.koinApplication.koin
    }
}

class InitKoinContentProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        MyKoinContext.koinApplication = koinApplication {
            androidContext(context.applicationContext)
            modules(module{
                viewModel { FooViewModel() }
            })
        }
        return true
    }
}

class FooActivity: AppCompactActivity(), MyKoinComponent {
    private val viewModel: FooViewModel by viewModel()
}

Ref: https://insert -koin.io / документы / 2,0 / документы / ссылки / index.html # _koin_context_isolation

0 голосов
/ 24 мая 2019

Под дизайном startKoin подразумевается вызов из класса Application.В библиотеке вы можете указать параметр: вызывать startKoin или нет.Но я сомневаюсь, что включение таких вещей, как Коин в библиотеки, является хорошей практикой.Что, если в приложение уже входит Koin, но другой версии?

...