如何使用Android Hilt为含@AssistedInject的类创建@Provides函数
解决方案:动态参数下的Pager依赖注入
核心结论
不能直接给带@AssistedInject的类写@Provides函数——因为@Provides用于提供编译时可确定依赖的实例,而@Assisted标记的是运行时动态参数,Dagger无法提前注入这类参数。最佳实践是通过工厂模式封装Pager的创建逻辑,把动态参数的传入延迟到使用阶段。
步骤1:修正AssistedInject用法
你手动实现的CreatorPagingSourceFactoryProvider是冗余的——Dagger会自动实现@AssistedFactory接口,直接删除这个类,保留@AssistedFactory定义即可:
internal class CreatorPagingSource @AssistedInject constructor( @Assisted private val creatorId: Int, private val creatorDataSource: CreatorDataSource ) : PagingSource<Int, ComicDto>() { // 你的分页逻辑... @AssistedFactory interface Factory { fun create(creatorId: Int): CreatorPagingSource } }
步骤2:提供Pager工厂函数
在Module中提供一个接受动态参数并返回Pager的函数类型,让Dagger注入这个工厂,而不是直接注入Pager实例:
@Qualifier annotation class CreatorPagerFactory private const val PAGE_SIZE = 10 @Module @InstallIn(SingletonComponent::class) internal object CreatorPagerModule { @CreatorPagerFactory @Provides fun provideCreatorPagerFactory( config: PagingConfig, pagingSourceFactory: CreatorPagingSource.Factory ): (Int) -> Pager<Int, ComicDto> { return { creatorId -> Pager( config = config, pagingSourceFactory = { pagingSourceFactory.create(creatorId) } ) } } // 如果PagingConfig已在其他Module提供,可省略此方法 @Provides fun providePagingConfig(): PagingConfig = PagingConfig(pageSize = PAGE_SIZE) }
步骤3:在Repository中使用工厂
注入这个工厂函数,调用时传入动态的creatorId即可获取对应的Pager:
internal class CreatorRepository @Inject constructor( @CreatorPagerFactory private val pagerFactory: (Int) -> Pager<Int, ComicDto> ) { fun getCreatorComics(creatorId: Int): Pager<Int, ComicDto> { return pagerFactory(creatorId) } }
为什么这是最佳实践?
- 解耦依赖与动态参数:把Dagger负责的依赖注入(
CreatorDataSource、PagingConfig)和运行时动态参数(creatorId)分开,符合单一职责原则。 - 减少冗余代码:利用Dagger自动生成的
@AssistedFactory,避免手动实现工厂类的重复代码。 - 保持依赖注入的一致性:所有依赖仍然通过Dagger管理,避免手动创建实例导致的依赖泄漏或测试困难。
内容的提问来源于stack exchange,提问作者Gibran Lyra
相关产品推荐
相关产品推荐

