Koin Android-KMM嵌套作用域注入失败:找不到AppointmentsRepository定义
Koin依赖注入错误:找不到AppointmentsRepository定义的解决方法
问题描述
使用Koin进行依赖注入时触发错误:
No definition found for class:'com.flow.domain.repository.AppointmentsRepository'. Check your definitions!
期望AppointmentsRepository的生命周期与UserInfoContainer作用域绑定,但注入流程无法正常执行。
核心问题分析
- 作用域不匹配:
AppointmentsRepository定义在UserInfoContainer的专属作用域中,但AppointmentsUseCase默认从全局作用域查找实例,导致找不到对应定义。 - Scope初始化不规范:
UserInfoContainer中getOrCreateScope()未指定与配置中匹配的作用域标识,创建的作用域和定义的scope<UserInfoContainer>不关联。 - 空指针风险:构造
AppointmentsRepositoryImplementation时直接使用user!!.clinicId,未处理用户未初始化的场景。
解决方案
1. 修正UserInfoContainer的Scope初始化逻辑
确保创建的作用域与Koin配置中定义的scope<UserInfoContainer>匹配,同时在用户变更时重建作用域:
class UserInfoContainer(private val encryptedLocalDatabase: EncryptedLocalDatabase) : KoinScopeComponent { override val scope: Scope get() = getOrCreateScope(named<UserInfoContainer>(), this).value var user: User? get() = encryptedLocalDatabase.user set(it) { if (it != encryptedLocalDatabase.user) { encryptedLocalDatabase.user = it scope.close() // 用户变更后重建作用域,保证后续实例使用最新用户数据 getOrCreateScope(named<UserInfoContainer>(), this) } } }
2. 在AppointmentsUseCase中指定作用域注入
由于AppointmentsRepository属于UserInfoContainer的作用域,注入时必须明确指定作用域来源,以下两种方式二选一:
方式一:让UseCase关联UserInfoContainer的作用域
class AppointmentsUseCase : KoinComponent, KoinScopeComponent { // 绑定到UserInfoContainer的作用域 override val scope: Scope get() = get<UserInfoContainer>().scope private val appointmentsRepository: AppointmentsRepository by inject(scope = { scope }) suspend fun getAppointments(startDate: LocalDateTime, endDate: LocalDateTime): List<Appointment> = appointmentsRepository.getAppointments(startDate, endDate) }
方式二:直接指定注入的作用域
class AppointmentsUseCase : KoinComponent { private val userInfoContainer = get<UserInfoContainer>() private val appointmentsRepository: AppointmentsRepository by inject(scope = { userInfoContainer.scope }) suspend fun getAppointments(startDate: LocalDateTime, endDate: LocalDateTime): List<Appointment> = appointmentsRepository.getAppointments(startDate, endDate) }
3. 优化Repository构造的安全性
添加非空校验,避免空指针异常:
single { UserInfoContainer(encryptedLocalDatabase = get()) } scope<UserInfoContainer> { scoped<AppointmentsRepository> { val userInfoContainer = get<UserInfoContainer>() checkNotNull(userInfoContainer.user) { "User必须先初始化才能创建AppointmentsRepository" } AppointmentsRepositoryImplementation( apiService = get(), clinicId = userInfoContainer.user!!.clinicId ) } }
内容的提问来源于stack exchange,提问作者EliodeBeirut
相关产品推荐
相关产品推荐

