Hilt 模块中的@AssistedInject 参数
@AssistedInject parameters in Hilt modules
我在将项目从 Dagger 迁移到 Hilt 时遇到问题。
遗留代码使用 class Foo 具有应用程序本身的配置(如国家代码等),此 的一个实例Foo class 在用户从触发异步调用的按钮中选择区域后检索。
这个Foo实例用于创建一个FooModule并分配给依赖图如下:
override fun onFooReceived(foo: Foo) {
DaggerFooComponent.Builder()
.fooModule(FooModule(foo))
.mainAppComponent(appComponent)
.build()
}
此外,这个 Foo class 用于创建 Factory class returns 不同 classes 的实例(如 RetrofitApiClients)取决于所述 foo class.
的属性
FooModule class 看起来像这样:
@Module
class FooModule(private val foo: Foo) {
@Provides
fun provideFoo(): Foo = foo
@Provides
fun provideRetrofitClient(): RetrofitClient = foo.factory.getRetrofitClient(foo)
@Provides
fun provideOtherClass(): OtherClass = foo.factory.getOtherClass(foo)
}
FooFactory class 只是一个具有不同实现的接口,它实例化 classes 依赖于 Foo属性。
interface FooFactory {
fun getOtherClass(foo: Foo): OtherClass
fun getRetrofitClient(foo: Foo): RetrofitClient
}
实现如下所示:
class NorthRegionFooFactory: FooFactory {
override fun getOtherClass(foo: Foo) = OtherClass(foo.regionId)
override fun getRetrofitClient(foo: Foo) = RetrofitClient(foo.getConfig("base_url_key"))
}
class SouthRegionFooFactory: FooFactory {
override fun getOtherClass(foo: Foo) = throw Exception("OtherClass not supported in this region")
override fun getRetrofitClient(foo: Foo) = RetrofitClient(SOUTH_REGION_MOCK_CONSTANT)
}
到目前为止我尝试了什么
我想到解决这个问题的方法是 @AssistedInject,我将代码修改为如下所示:
FooModule:
@Module
@InstallsIn(SingletonComponent::class)
class FooModule @AssistedInject constructor(@Assisted val foo: Foo) {
@Provides
fun provideFoo(): Foo = foo
@Provides
fun provideRetrofitClient(): RetrofitClient = foo.factory.getRetrofitClient(foo)
@Provides
fun provideOtherClass(): OtherClass = foo.factory.getOtherClass(foo)
}
FooModuleFactory(新class)
@AssistedFactory
interface FooModuleFactory {
fun create(foo: Foo): FooModule
}
并且当接收到 Foo 实例时...
选择区域活动
@AndroidEntryPoint
class SelectRegionActivity: AppCompatActivity {
@Inject
lateinit var fooModuleFactory: FooModuleFactory
override fun onFooReceived(foo: Foo) {
fooModuleFactory.create(foo)
}
}
但这不起作用,因为 Hilt 需要模块的空构造函数:
public final class FooModule {
^
Modules that need to be instantiated by Hilt must have a visible, empty constructor.
[Hilt] Processing did not complete. See error above for details.
我尝试添加 @Assisted Foo 构造函数作为 FooModule 的辅助构造函数,并且让主构造函数为空,但我得到同样的错误。
是否可以在 Hilt 模块中使用 @Assisted 属性?
作为错误状态,所有模块都必须有空的构造函数,否则 dagger 将无法创建组件中引用的模块 类 的实例。模块将始终作为映射如何查找依赖项工作。
您需要在您尝试注入的 类 中添加 Foo
作为依赖项,而不是 dagger 模块。那样的话,你就可以使用辅助注射了。
我在将项目从 Dagger 迁移到 Hilt 时遇到问题。
遗留代码使用 class Foo 具有应用程序本身的配置(如国家代码等),此 的一个实例Foo class 在用户从触发异步调用的按钮中选择区域后检索。
这个Foo实例用于创建一个FooModule并分配给依赖图如下:
override fun onFooReceived(foo: Foo) {
DaggerFooComponent.Builder()
.fooModule(FooModule(foo))
.mainAppComponent(appComponent)
.build()
}
此外,这个 Foo class 用于创建 Factory class returns 不同 classes 的实例(如 RetrofitApiClients)取决于所述 foo class.
的属性FooModule class 看起来像这样:
@Module
class FooModule(private val foo: Foo) {
@Provides
fun provideFoo(): Foo = foo
@Provides
fun provideRetrofitClient(): RetrofitClient = foo.factory.getRetrofitClient(foo)
@Provides
fun provideOtherClass(): OtherClass = foo.factory.getOtherClass(foo)
}
FooFactory class 只是一个具有不同实现的接口,它实例化 classes 依赖于 Foo属性。
interface FooFactory {
fun getOtherClass(foo: Foo): OtherClass
fun getRetrofitClient(foo: Foo): RetrofitClient
}
实现如下所示:
class NorthRegionFooFactory: FooFactory {
override fun getOtherClass(foo: Foo) = OtherClass(foo.regionId)
override fun getRetrofitClient(foo: Foo) = RetrofitClient(foo.getConfig("base_url_key"))
}
class SouthRegionFooFactory: FooFactory {
override fun getOtherClass(foo: Foo) = throw Exception("OtherClass not supported in this region")
override fun getRetrofitClient(foo: Foo) = RetrofitClient(SOUTH_REGION_MOCK_CONSTANT)
}
到目前为止我尝试了什么
我想到解决这个问题的方法是 @AssistedInject,我将代码修改为如下所示:
FooModule:
@Module
@InstallsIn(SingletonComponent::class)
class FooModule @AssistedInject constructor(@Assisted val foo: Foo) {
@Provides
fun provideFoo(): Foo = foo
@Provides
fun provideRetrofitClient(): RetrofitClient = foo.factory.getRetrofitClient(foo)
@Provides
fun provideOtherClass(): OtherClass = foo.factory.getOtherClass(foo)
}
FooModuleFactory(新class)
@AssistedFactory
interface FooModuleFactory {
fun create(foo: Foo): FooModule
}
并且当接收到 Foo 实例时...
选择区域活动
@AndroidEntryPoint
class SelectRegionActivity: AppCompatActivity {
@Inject
lateinit var fooModuleFactory: FooModuleFactory
override fun onFooReceived(foo: Foo) {
fooModuleFactory.create(foo)
}
}
但这不起作用,因为 Hilt 需要模块的空构造函数:
public final class FooModule {
^
Modules that need to be instantiated by Hilt must have a visible, empty constructor.
[Hilt] Processing did not complete. See error above for details.
我尝试添加 @Assisted Foo 构造函数作为 FooModule 的辅助构造函数,并且让主构造函数为空,但我得到同样的错误。
是否可以在 Hilt 模块中使用 @Assisted 属性?
作为错误状态,所有模块都必须有空的构造函数,否则 dagger 将无法创建组件中引用的模块 类 的实例。模块将始终作为映射如何查找依赖项工作。
您需要在您尝试注入的 类 中添加 Foo
作为依赖项,而不是 dagger 模块。那样的话,你就可以使用辅助注射了。