org.koin.core.error.InstanceCreationException: 无法为 [Factory:'com.pokemonsearch.presentation.search.



我在Kotlin应用程序中使用Koin作为依赖注入框架。我正在尝试使用协程将数据保存到房间数据库。我有一个用例"从视图模型调用的类。在运行应用程序时,应用程序崩溃,错误如下。当我检查时,我知道koin找不到一些依赖项。有谁能给我一个解决办法吗?请在下面找到存储库、用例、视图模型、数据库和di模块

Process: com.debin.pokemonsearch, PID: 16027
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.debin.pokemonsearch/com.debin.pokemonsearch.HomeActivity}: org.koin.core.error.InstanceCreationException: Could not create instance for [Factory:'com.debin.pokemonsearch.presentation.search.SearchViewModel']
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817`
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Factory:'com.debin.pokemonsearch.presentation.search.SearchViewModel']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at org.koin.android.viewmodel.ViewModelFactoryKt$defaultViewModelFactory$1.create(ViewModelFactory.kt:13)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at org.koin.android.viewmodel.ViewModelResolutionKt.get(ViewModelResolution.kt:21)
at org.koin.android.viewmodel.ViewModelResolutionKt.resolveInstance(ViewModelResolution.kt:10)
at org.koin.android.viewmodel.scope.ScopeExtKt.getViewModel(ScopeExt.kt:68)
at org.koin.android.viewmodel.scope.ScopeExtKt.getViewModel(ScopeExt.kt:56)
at org.koin.android.viewmodel.koin.KoinExtKt.getViewModel(KoinExt.kt:34)
at org.koin.android.viewmodel.ext.android.ViewModelStoreOwnerExtKt.getViewModel(ViewModelStoreOwnerExt.kt:66)
at com.debin.pokemonsearch.presentation.search.SearchFragment$$special$$inlined$viewModel$1.invoke(ViewModelStoreOwnerExt.kt:71)
at com.debin.pokemonsearch.presentation.search.SearchFragment$$special$$inlined$viewModel$1.invoke(Unknown Source:0)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
at com.debin.pokemonsearch.presentation.search.SearchFragment.getViewModel(Unknown Source:2)
at com.debin.pokemonsearch.presentation.search.SearchFragment.observePokemon(SearchFragment.kt:39)
at com.debin.pokemonsearch.presentation.search.SearchFragment.onViewCreated(SearchFragment.kt:31)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2577)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2722)
at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:346)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1188)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
2021-01-24 19:49:54.088 16027-16027/com.debin.pokemonsearch E/AndroidRuntime:     at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2577)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1333)
at android.app.Activity.performStart(Activity.java:6992)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780)
... 9 more
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Factory:'com.debin.pokemonsearch.pokemoncore.interactors.AddToFavourites']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.debin.pokemonsearch.di.ViewModelModuleKt$viewModelModule$1$1.invoke(ViewModelModule.kt:24)
at com.debin.pokemonsearch.di.ViewModelModuleKt$viewModelModule$1$1.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
... 49 more
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Single:'com.debin.pokemonsearch.pokemoncore.domain.repository.IPokemonCoreRepository']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:40)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:48)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.debin.pokemonsearch.di.UseCaseModuleKt$useCaseModule$1$3.invoke(UseCaseModule.kt:23)
at com.debin.pokemonsearch.di.UseCaseModuleKt$useCaseModule$1$3.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
... 56 more
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Single:'com.debin.pokemonsearch.pokemoncore.data.datasource.PokemonCoreDataSource']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:40)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:48)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.debin.pokemonsearch.di.RepositoryModuleKt$repositoryModule$1$3.invoke(RepositoryModule.kt:19)
at com.debin.pokemonsearch.di.RepositoryModuleKt$repositoryModule$1$3.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
... 64 more
Caused by: org.koin.core.error.NoBeanDefFoundException: No definition found for class:'com.debin.pokemonsearch.framework.db.PokemonDatabase'. Check your definitions!
at org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:246)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:216)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.debin.pokemonsearch.di.DataSourceModuleKt$dataSourceModule$1$3.invoke(DataSourceModule.kt:19)
at com.debin.pokemonsearch.di.DataSourceModuleKt$dataSourceModule$1$3.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
... 72 more

AddToFavourites Usecase:

class AddToFavourites(private val coreRepository: IPokemonCoreRepository) {
suspend fun invokeAddToFavourites(pokemon: Pokemon) {
coreRepository.addPokemonToFavourites(pokemon)
}
}

域层中的存储库接口和模型

interface IPokemonCoreRepository {
suspend fun addPokemonToFavourites(pokemon: Pokemon)
suspend fun getFavouritePokemon() : List<Pokemon>
suspend fun removePokemonFromFavourite(pokemon: Pokemon)
}
data class Pokemon(
val id : Int,
val name : String,
val description : String,
val imageUrl : String
)

数据层的存储库实现和数据过程:

class PokemonCoreRepository(private val dataSource: PokemonCoreDataSource) : IPokemonCoreRepository {
override suspend fun addPokemonToFavourites(pokemon: Pokemon) {
return dataSource.addPokemonToFavourites(pokemon)
}

override suspend fun getFavouritePokemon(): List<Pokemon> {
return dataSource.getFavouritePokemon()
}

override suspend fun removePokemonFromFavourite(pokemon: Pokemon) {
return dataSource.removePokemonFromFavourite(pokemon)
}
}
interface PokemonCoreDataSource {
suspend fun addPokemonToFavourites(pokemon: Pokemon)
suspend fun getFavouritePokemon() : List<Pokemon>
suspend fun removePokemonFromFavourite(pokemon: Pokemon)
}

数据库在框架层的实现:

class PokemonCoreDataSourceImpl(private val database : PokemonDatabase) : PokemonCoreDataSource{

override suspend fun addPokemonToFavourites(pokemon: Pokemon) {
return database.pfDao.addToFavourite(PokemonFavouriteEntity(id = pokemon.id, name = pokemon.name,
description = pokemon.description, imageUrl = pokemon.imageUrl))
}

override suspend fun getFavouritePokemon(): List<Pokemon> {
return database.pfDao.getFavouritePokemon().map {
Pokemon(id = it.id, name = it.name, description = it.description, imageUrl = it.imageUrl)
}
}

override suspend fun removePokemonFromFavourite(pokemon: Pokemon) {
return database.pfDao.removeFromFavourite(PokemonFavouriteEntity(
id = pokemon.id, name = pokemon.name,
description = pokemon.description, imageUrl = pokemon.imageUrl
))
}
}

Koin di Modules:

val useCaseModule = module {
factory { AddToFavourites(get()) }
factory { GetFavourites(get()) }
factory { RemoveFromFavourite(get()) }
}

val repositoryModule = module {
single<IPokemonCoreRepository> { PokemonCoreRepository(get()) }
}

val dataSourceModule = module {
single<PokemonCoreDataSource> { PokemonCoreDataSourceImpl(get()) }
}

val databaseModule = module {
single { PokemonDatabaseFactory.getDBInstance(get()) }
}

val viewModelModule = module {
viewModel { SearchViewModel(get(), get(), get()) }
}

框架层中的数据库和实体:

@Database(entities = [PokemonFavouriteEntity::class], version = 1, exportSchema = false)
abstract class PokemonDatabase : RoomDatabase() {
abstract val pfDao : PokemonFavouriteDao
}

object PokemonDatabaseFactory {
fun getDBInstance(context: Context) {
Room.databaseBuilder(context, PokemonDatabase::class.java, "PokemonDB")
.fallbackToDestructiveMigration()
.build()
}
}

@Dao
interface PokemonFavouriteDao {
@Insert(onConflict = REPLACE)
suspend fun addToFavourite(pokemon : PokemonFavouriteEntity)
}

@Entity(tableName = "favourites")
data class PokemonFavouriteEntity(
@PrimaryKey(autoGenerate = true) val id : Int,
@ColumnInfo(name = "pokemonName") val name : String = "",
@ColumnInfo(name = "pokemonDescription") val description : String = "",
@ColumnInfo(name =  "pokemonImage")val imageUrl : String = ""
)

表示层中的视图模型:

class SearchViewModel (private val getPokemonDescription: GetPokemonDescription,
private val getPokemonSprites: GetPokemonSprites,
private val addToFavourites: AddToFavourites) : ViewModel() {
private val _pokemon = MutableLiveData<Resource<PokemonResponse>>()
private val _pokemonSprites = MutableLiveData<Resource<List<String>>>()
private val _pokemonSpecies = MutableLiveData<Resource<PokemonSpeciesResponse>>()
val pokemon: LiveData<Resource<PokemonResponse>> get() = _pokemon
val pokemonSpecies: LiveData<Resource<PokemonSpeciesResponse>> get() = _pokemonSpecies

fun getPokemonDetails(pokemonName: String) {
_pokemon.value = Resource.Loading()
getPokemonSprites.execute(PokemonSubscriber(), pokemonName)
}
fun getPokemonSpeciesDetails(pokemonName: String) {
_pokemonSpecies.value = Resource.Loading()
getPokemonDescription.execute(PokemonSpeciesSubscriber(), pokemonName)
}
fun addToFavourite() {
viewModelScope.launch {
withContext(Dispatchers.IO) {
addToFavourites.invokeAddToFavourites(getPokemonDetails())
}
}
}
inner class PokemonSubscriber : DisposableSingleObserver<PokemonResponse>() {
override fun onSuccess(pokemonResponse: PokemonResponse) {
_pokemon.value = Resource.Success(pokemonResponse)
}
override fun onError(error: Throwable) {
_pokemon.value = Resource.Error(error.message)
}
}
inner class PokemonSpeciesSubscriber : DisposableSingleObserver<PokemonSpeciesResponse>() {
override fun onSuccess(pokemonSpeciesResponse: PokemonSpeciesResponse) {
_pokemonSpecies.value = Resource.Success(pokemonSpeciesResponse)
}
override fun onError(error: Throwable) {
_pokemonSpecies.value = Resource.Error(error.message)
}
}
private fun getPokemonDetails(): Pokemon {
var pokemonId = 0
var pokemonName = ""
var pokemonDescription = ""
var pokemonImage = ""
_pokemon.observeForever {
when (it) {
is Resource.Success -> {
pokemonImage = it.result.sprites.front_default
}
else -> {
}
}
}
_pokemonSpecies.observeForever {
when (it) {
is Resource.Success -> {
pokemonId = it.result.id
pokemonName = it.result.name
pokemonDescription = it.result.flavor_text_entries[0].flavor_text
}
else -> {
}
}
}
return Pokemon(pokemonId, pokemonName, pokemonDescription, pokemonImage)
}
override fun onCleared() {
super.onCleared()
getPokemonDescription.dispose()
getPokemonSprites.dispose()
}
}

没有返回创建的数据库实例。将return语句添加到工厂函数或使用=

返回:

object PokemonDatabaseFactory {
fun getDBInstance(context: Context) =
Room.databaseBuilder(context, PokemonDatabase::class.java, "PokemonDB")
.fallbackToDestructiveMigration()
.build()

}

实际上,在数据库中不需要工厂函数。您可以通过Koin从模块直接创建DB对象,如下所示:

single {
Room.databaseBuilder(context, PokemonDatabase::class.java, "PokemonDB")
.fallbackToDestructiveMigration()
.build()
}

相关内容

最新更新