1

我在将项目从 Dagger 迁移到 Hilt 时遇到问题。

遗留代码使用具有应用程序本身配置的类Foo (如国家代码等),在用户从触发异步调用的按钮中选择区域后检索此Foo类的实例。

Foo实例用于创建FooModule并分配给依赖关系图,如下所示:

override fun onFooReceived(foo: Foo) {
   DaggerFooComponent.Builder()
      .fooModule(FooModule(foo))
      .mainAppComponent(appComponent)
      .build()
}

此外,这个Foo类用于创建一个Factory类,该类根据所述 foo 类的属性返回不同类的实例(如 RetrofitApiClients)。

FooModule 类看起来像这样:

@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类只是一个具有不同实现的接口,这些实现依赖于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,我将代码修改为如下所示:

食品模块:

@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(新类)

@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属性吗?

4

1 回答 1

1

作为错误状态,所有模块都必须有空的构造函数,否则 dagger 将无法创建组件中引用的模块类的实例。模块将始终作为如何查找依赖项的映射。

您需要Foo在尝试注入的类中添加依赖项,而不是匕首模块。在这种情况下,您将能够使用辅助注射。

于 2021-10-19T10:38:31.027 回答