我有两个类,我可以让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
类上使用了完全相同的方法,并且可行。@Binds
声明,我将完全理解此错误。为什么现在会出现此错误?
[像这样修改您的模块:
@Module
internal abstract class MyModule {
@Binds
abstract fun bindsTrackEventUseCase(useCase: TrackEvent): UseCase<Boolean, TrackingEvent>
// New
@Binds
abstract fun bindsGetUserTrackingProperties(useCase: GetUserTrackingProperties): NoParamUseCase<UserTrackingPropertiesResult>
}