Dagger迁移Hilt时Hilt模块中是否支持使用@AssistedInject传递参数?
Hilt 迁移适配方案
核心问题解答
首先明确:Hilt 模块完全不支持使用 @AssistedInject 或传入 @Assisted 属性。
Hilt 的设计逻辑是所有标注了 @InstallIn 的模块,都会在编译期直接绑定到对应的 Component,由 Hilt 框架负责实例化模块,因此要求所有非 object 类型的模块必须提供公开无参构造,不支持开发者在运行时动态传入参数构造模块,你之前的写法从根上不符合 Hilt 的模块规则。
适配方案1:全局单 Foo 实例(推荐适配多数场景)
如果你的应用同一时间只会存在一个有效 Foo 实例,用全局 Holder 存储运行时生成的 Foo 即可:
步骤1:定义 Foo 单例容器
@Singleton class FooHolder @Inject constructor() { var currentFoo: Foo? = null }
步骤2:修改 FooModule
把模块改成无状态的 object 类型,从 Holder 中取 Foo 实例:
@Module @InstallIn(SingletonComponent::class) object FooModule { @Provides fun provideFoo(fooHolder: FooHolder): Foo { return requireNotNull(fooHolder.currentFoo) { "请先选择区域初始化 Foo 实例" } } @Provides fun provideRetrofitClient(foo: Foo): RetrofitClient = foo.factory.getRetrofitClient(foo) @Provides fun provideOtherClass(foo: Foo): OtherClass = foo.factory.getOtherClass(foo) }
步骤3:用户选择区域后赋值
@AndroidEntryPoint class SelectRegionActivity: AppCompatActivity() { @Inject lateinit var fooHolder: FooHolder override fun onFooReceived(foo: Foo) { fooHolder.currentFoo = foo // 后续业务页面直接注入 Foo、RetrofitClient 等依赖即可正常使用 } }
适配方案2:自定义子组件(兼容原 Dagger 动态 Component 写法)
如果需要支持多 Foo 实例隔离的场景,用 Hilt 子组件实现和原 Dagger 一致的逻辑:
步骤1:定义 Foo 子组件
@Subcomponent interface FooComponent { // 声明需要注入的目标类,或者直接暴露依赖 fun retrofitClient(): RetrofitClient fun otherClass(): OtherClass @Subcomponent.Factory interface Factory { fun create(@BindsInstance foo: Foo): FooComponent } // 将子组件 Factory 安装到 SingletonComponent @Module @InstallIn(SingletonComponent::class) interface SubcomponentBindModule { @Binds fun bindFactory(impl: FooComponent.Factory): FooComponent.Factory } }
步骤2:获取子组件 Factory 创建实例
@AndroidEntryPoint class SelectRegionActivity: AppCompatActivity() { @Inject lateinit var fooComponentFactory: FooComponent.Factory override fun onFooReceived(foo: Foo) { val fooComponent = fooComponentFactory.create(foo) // 后续需要 Foo 相关依赖的类,传入 fooComponent 完成注入即可 } }
内容的提问来源于stack exchange,提问作者Alfredo Bejarano
相关产品推荐
相关产品推荐

