交换接口的凝固时,匕首2 MissingBinding

问题描述 投票:1回答:1

我有两个类,我可以让Dagger找到并注入它们以供我成功使用:

TrackEvent

class TrackEvent @Inject constructor(
    private val getTrackingProperties: GetUserTrackingProperties,
    private val eventTracker: EventTracker,
    private val sessionManager: SessionManager
) : UseCase<Boolean, TrackingEvent> {

    override suspend operator fun invoke(params: TrackingEvent): Boolean {
        val userProperties: UserTrackingPropertiesResult = getTrackingProperties.invoke()

        return if (userProperties is UserTrackingPropertiesResult.UserTrackingProperties && sessionManager.shouldTrackEvents()) {
            eventTracker.track(params, userProperties)
            true
        } else {
            false
        }
    }

GetUserTrackingProperties(注意:在TrackEvent中用作依赖项)

class GetUserTrackingProperties @Inject constructor(
    private val getUser: GetUser,
    private val propertiesFactory: UserTrackingPropertiesFactory
) {
    override suspend operator fun invoke(): UserTrackingPropertiesResult {
        val getUserResult: GetUserResult = getUser()

        return if (getUserResult is GetUserResult.Successful) {
            propertiesFactory.createProperties(
                user = getUserResult.user
            )
        } else {
            UserTrackingPropertiesResult.FailedToGetProperties
        }
    }
}

[TrackEvent@Module带注释的接口中有一个条目,因为它是UseCase接口的实现:

@Component(modules = [MyModule::class])
interface ShiftsComponent {
    fun inject(homeFragment: HomeFragment)
}

@Module
interface MyModule {

    @Binds
    fun bindsTrackEventUseCase(useCase: TrackEvent): UseCase<Boolean, TrackingEvent>
}

用例界面

interface UseCase<out T, in P> {

    suspend operator fun invoke(params: P): T
}

interface NoParamUseCase<out T> {

    suspend operator fun invoke(): T
}

我想做的是将接口注入到TrackEvent中,而不是具体的GetUserTrackingProperties中。所以我让GetUserTrackingProperties实现了NoParamUseCase

class GetUserTrackingProperties @Inject constructor(
    private val getUser: GetUser,
    private val propertiesFactory: UserTrackingPropertiesFactory
): NoParamUseCase<UserTrackingPropertiesResult> {
    override suspend operator fun invoke(): UserTrackingPropertiesResult {
        val getUserResult: GetUserResult = getUser()

        return if (getUserResult is GetUserResult.Successful) {
            propertiesFactory.createProperties(
                user = getUserResult.user
            )
        } else {
            UserTrackingPropertiesResult.FailedToGetProperties
        }
    }
}

更新TrackEvent以注入接口:

class TrackEvent @Inject constructor(
    private val getTrackingProperties: NoParamUseCase<UserTrackingPropertiesResult>,
    private val eventTracker: EventTracker,
    private val sessionManager: SessionManager
) : UseCase<Boolean, TrackingEvent> {

    override suspend operator fun invoke(params: TrackingEvent): Boolean {
        val userProperties: UserTrackingPropertiesResult = getTrackingProperties.invoke()

        return if (userProperties is UserTrackingPropertiesResult.UserTrackingProperties && sessionManager.shouldTrackEvents()) {
            eventTracker.track(params, userProperties)
            true
        } else {
            false
        }
    }
}

…更新MyModule以通知Dagger我想使用哪种实现:

@Module
interface MyModule {

    @Binds
    fun bindsTrackEventUseCase(useCase: TrackEvent): UseCase<Boolean, TrackingEvent>

    // New
    @Binds
    fun bindsGetUserTrackingProperties(useCase: GetUserTrackingProperties): NoParamUseCase<UserTrackingPropertiesResult>
}

Dagger现在声称缺少绑定,我需要声明一个@Provides带注释的方法:

error: [Dagger/MissingBinding] com.myapp.core.domain.usecase.NoParamUseCase<? extends com.myapp.core.tracking.UserTrackingPropertiesResult> cannot be provided without an @Provides-annotated method.
public abstract interface MyComponent {
                ^
      com.myapp.core.domain.usecase.NoParamUseCase<? extends com.myapp.core.tracking.UserTrackingPropertiesResult> is injected at
          com.myapp.tasks.tracking.domain.usecase.TrackEvent(getTrackingProperties, …)
          …

据我所知,这是不正确的:

  • 虽然,在这种情况下,我选择了@Binds,将其替换为@Provides,并在此处手动提供依赖项会产生相同的错误。
  • 我在TrackEvent类上使用了完全相同的方法,并且可行。
  • 我已经更改的only事情是,我想提供一个接口。如果不提供@Binds声明,我将完全理解此错误。

为什么现在会出现此错误?

android kotlin dependency-injection dagger-2
1个回答
0
投票

[像这样修改您的模块:

@Module
internal abstract class MyModule {

    @Binds
    abstract fun bindsTrackEventUseCase(useCase: TrackEvent): UseCase<Boolean, TrackingEvent>

    // New
    @Binds
    abstract fun bindsGetUserTrackingProperties(useCase: GetUserTrackingProperties): NoParamUseCase<UserTrackingPropertiesResult>
}
© www.soinside.com 2019 - 2024. All rights reserved.