Коин - проблема с вложенными областями для Android - PullRequest
2 голосов
/ 06 января 2020

Используемая версия Koin: 2.1.0-alpha-8

У меня есть функция FeatureActivity, в которой размещены два фрагмента: 1) FirstFragment и 2) SecondFragment

Мой модуль выглядит следующим образом

val featureModule = module {

    scope<FeatureActivity> {

        // FeatureDao
        scoped {
            val appDatabase: AppDatabase = get()
            appDatabase.featureDao()
        }

        scope(named(FirstFragment.SCOPE_ID)) {
            scoped { FirstFragmentRepository(get()) }
            viewModel { FirstFragmentViewModel(get()) } // needs FeatureDao
            scoped { FirstFragmentAdapter(get()) }
        }

        scope(named(SecondFragment.SCOPE_ID)) {
            scoped { SecondFragmentRepository(get()) }
            viewModel { SecondFragmentViewModel(get()) } // needs FeatureDao
            scoped { SecondFragmentAdapter(get()) }
        }

    }

С помощью области я хочу ограничить доступ к FirstFragmentRepository, FirstFragmentViewModel et c. только к первому фрагменту и SecondFragmentRepository, SecondFragmentViewModel et c. только к SecondFragment.

Вопрос 1: Тем не менее, моим ViewModels требуется инъекция FeatureDao. Как получить доступ к FeatureDao, если это часть родительской области [Область действия FeatureActivity]? FeatureDao находится в ActivityScope, потому что это необходимо для FirstFragment и SecondFragment

Моя активность выглядит следующим образом

class FeatureActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
         loadKoinModules(featureModule)
    }

    override fun onDestroy() {
        super.onDestroy()
        unloadKoinModules(featureModule)
    }

}

и мой FirstFragment выглядит следующим образом

class FirstFragment : Fragment() {

    companion object{
        const val SCOPE_ID = "FirstFragment"
    }

    val scope = getKoin().getOrCreateScope(SCOPE_ID, named(SCOPE_ID))
    val viewModel   by lazy {  scope.get<FirstFragmentViewModel>()}
    val adapter  by lazy { scope.get<FirstFragmentAdapter>() }

}

Когда я делаю это getKoin().getOrCreateScope(SCOPE_ID, named(SCOPE_ID)), приложение вылетает

Caused by: org.koin.core.error.NoScopeDefFoundException: No Scope Definition found for qualifer 'FirstFragment'
        at org.koin.core.registry.ScopeRegistry.createScope(ScopeRegistry.kt:128)
        at org.koin.core.Koin.createScope(Koin.kt:181)
        at org.koin.core.Koin.getOrCreateScope(Koin.kt:203)
        at com.temp.testkoin.FirstFragment.<init>(FirstFragment.kt:24)

Однако, если я использую val scope = getKoin().getScopeOrNull(SCOPE_ID), область действия устанавливается на ноль.

Я прошел через несколько вопросы на этом форуме, и ни один из них не похож на тот, который я хочу достичь.

  • Вопрос 2: Мои области уже созданы. Почему тогда getScopeOrNull() возвращает ноль?
  • Вопрос 3: Я даже пытался это сделать, а getScopeOrNull() все еще возвращает ноль?
val featureModule = module {

    scope<FeatureActivity> {

        // FeatureDao
        scope(named("featureDao")) {
            scoped {
                val appDatabase: AppDatabase = get()
                appDatabase.featureDao()
            }
        }

        scope(named(FirstFragment.SCOPE_ID)) {
            scoped { FirstFragmentRepository(get()) }
            viewModel { FirstFragmentViewModel(getScope("featureDao").get()) }
            scoped { FirstFragmentAdapter(get()) }
        }

       ...
       ...

    }
  • Вопрос 4: Какой правильный способ получить указатель на мою область и правильно ввести мои зависимости?
  • Вопрос 5: Устойчивы ли области? Удаление вложенных областей действия scope(named(FirstFragment.SCOPE_ID)) и scope(named(SecondFragment.SCOPE_ID)) запускает процесс. Работает как положено. Однако доступ к Бину (из другой Области) в данном Области еще не поддерживается, или это так кажется. Независимо от того, сколько я стараюсь, он продолжает жаловаться org.koin.core.error.NoBeanDefFoundException: No definition found for class
...