Используемая версия 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