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 模块。那样的话,你就可以使用辅助注射了。