android - Dagger2 依赖循环使用@Binds 和@Inject 字段

标签 android kotlin dagger-2

每当我尝试将子组件与绑定(bind)对象一起使用时,我都会得到一个依赖循环。我有一个应用范围和一个 Activity 范围。在应用程序范围内,我创建了我的 Web 服务,然后当 Activity 打开时,我想创建一个存储对象、 Controller 和导航器(所有自定义类不是 androidx 类)并将它们注入(inject)到我的 androidx ViewModel 类中。但是当我这样做时,我会得到一个依赖循环。

我的顶级组件看起来像

@AppScope
@Component(modules = [AppModule::class])
interface AppComponent {

  val activityComponentBuilder: ActivityComponent.Builder
}

@Module(subcomponents = [ActivityComponent::class])
interface AppModule {

  @Binds
  fun mockWebService(mockWebService: MockWebService): MockWebService
}

接下来我的子组件看起来像
@ActivityComponent
@Subcomponent(modules = [ActivityModule::class])
interface ActivityComponent {

  fun inject(sharedViewModel: SharedViewModel)

  @Subcomponent.Builder
  interface Builder {
    @BindsInstance
    fun storage(storage: Storage): Builder

    fun build(): ActivityComponent
  }
}

在我的 Activity 模块中,我绑定(bind)了两个对象
  @Binds
  abstract fun controller(controller: Controller): Controller

  @Binds
  abstract fun navigator(navigator: Navigator): Navigator

每个对象都有一个@Inject 构造函数
class Navigator @Inject constructor(private val storage: Storage)

class Controller @Inject constructor(
  private val webService: MockWebService,
  private val navigator: Navigator,
  private val storage: Storage
) {

在我的共享 View 模型中,我尝试构建我的组件并注入(inject)字段
  @Inject
  lateinit var navigator: Navigator
  @Inject
  lateinit var controller: Controller

  init {
      MainApplication.component.activityComponentBuilder
        .storage(InMemoryStorage.from(UUID.randomUUID().toString()))
        .build()
        .inject(this)

  }

但 Dagger 不会 build 。我收到一个错误
[Dagger/DependencyCycle] Found a dependency cycle: public abstract interface AppComponent {

MockWebService is injected at di.AppModule.mockWebService(mockWebService)
MockWebService is injected at ActivityModule.Controller(webService, …)
Controller is injected at SharedViewModel.controller
SharedViewModel is injected at

但是错误消息在那里中断。我是否遗漏了如何使用子组件将对象放在图上然后将它们注入(inject)到对象中? Dagger 不可能吗?

最佳答案

@Binds用于让dagger知道一个接口(interface)的不同实现。你不需要@Binds在这里,因为 Navigator 和 Controller 是不实现任何接口(interface)的简单类。我认为 MockWebService 也是如此。此外,这些类有 @Inject constructor ,这意味着dagger可以实例化它们,我们不需要额外写@Provides这些类的功能。@Binds没有做任何范围界定。它唯一的工作就是告诉 dagger 不同的实现。您可以添加@XScope@Binds使一些对象范围。或者,您可以将范围注释添加到类声明中。 Here's如何将范围添加到类声明的示例。
至于依赖周期,我认为这是因为您告诉 ActivityComponent使用 ActivityModule并告诉 ActivityModule安装ActivityComponent .只做任何一个都应该是这样(我认为)。

关于android - Dagger2 依赖循环使用@Binds 和@Inject 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62077172/

相关文章:

android - Android打开另一个应用程序,然后单击按钮

java - JSON 字符串的字符串扫描和 JSON 解析之间的区别

android - 在Dagger2中,@Singleton注解的用途是什么?

java - Android - Dagger 注入(inject)非 Activity 或 fragment

android - 没有 firebase 的 AdMob 广告

java - Android Studio - 带选项卡布局的滑动 View

android - Kotlin IllegalStateException : Resource not found in classpath: kotlin/. kotlin_string_table

multithreading - 如何将协程直接分派(dispatch)到 JVM 上的主线程?

java - android-manifest 中的 android.stamp 是什么?

android - Android 服务中的 Hilt 注入(inject)