Dagger Hilt在MVP架构Model层注入Retrofit APIService失败问题
问题根因
你当前使用的是字段注入的方式给RegistrationModel注入依赖,但Hilt只会对其自身管理的类自动完成注入操作,你手动实例化的RegistrationModel(就是直接用RegistrationModel(presenter)创建对象的场景)没有经过Hilt的注入流程,所以@Inject标注的字段不会被赋值,就会出现注入不生效的问题。
可用解决方案
下面是3种常用的解决方式,你可以根据自己的项目架构选择:
方案1:构造函数注入(最推荐)
直接将依赖放到RegistrationModel的构造函数中,给构造函数加@Inject注解,让Hilt托管RegistrationModel的实例创建:
// 修改RegistrationModel的构造 class RegistrationModel @Inject constructor( @Named("ApiService") val apiServices: ApiServices, val presenter: RegistrationContract.Presenter ) : RegistrationContract.Model { // 删掉类内部之前声明的@Inject lateinit var apiServices字段 // 剩下的onDataReady等原有逻辑不用修改 }
如果你是在Presenter中创建RegistrationModel实例,只需要把RegistrationModel作为构造参数注入到Presenter中即可,Hilt会自动完成所有依赖的装配。
方案2:手动传入依赖(最省事)
因为你已经可以在FragmentRegistration中正常注入ApiServices,可以直接在创建RegistrationModel的时候把ApiServices作为构造参数传进去,不需要改动现有Hilt配置:
// 修改RegistrationModel构造 class RegistrationModel( val presenter: RegistrationContract.Presenter, val apiServices: ApiServices // 直接通过构造传参 ) : RegistrationContract.Model { // 删掉类内部之前声明的@Inject lateinit var apiServices字段 // 剩下的原有逻辑不用修改 } // 在Fragment中创建Model时传参 val registrationModel = RegistrationModel(presenter, apiServices)
方案3:通过EntryPoint手动触发注入(适配非Hilt托管类场景)
如果你一定要自己控制RegistrationModel的实例创建,又不想通过构造传参,可以用Hilt的EntryPoint手动获取依赖:
- 首先定义EntryPoint接口
@EntryPoint @InstallIn(SingletonComponent::class) interface RegistrationModelEntryPoint { @Named("ApiService") fun provideApiService(): ApiServices }
- 改造
RegistrationModel,在初始化时手动获取依赖
class RegistrationModel( val presenter: RegistrationContract.Presenter, context: Context ) : RegistrationContract.Model { lateinit var apiServices: ApiServices init { // 从Application的Hilt容器中获取ApiService实例 val entryPoint = EntryPointAccessors.fromApplication( context.applicationContext, RegistrationModelEntryPoint::class.java ) apiServices = entryPoint.provideApiService() } // 剩下的原有逻辑不用修改 }
内容的提问来源于stack exchange,提问作者Abu Sufian Shawon
相关产品推荐
相关产品推荐

