gpt4 book ai didi

android - 尝试使用 Dagger 解决依赖循环

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:43:31 26 4
gpt4 key购买 nike

dagger-android 2.16

我的 Dagger 模块中存在依赖循环错误。我想我知道问题是什么,但不确定如何解决。

这是错误信息:

Found a dependency cycle:
public interface LoginFragmentSubcomponent extends AndroidInjector<LoginFragment> {
presentation.login.request.LoginRequest is injected at
mobileui.login.di.LoginActivityModule.provideLoginResponseListener(…, loginRequest)
presentation.login.response.LoginResponseListener is injected at
mobileui.login.di.LoginActivityModule.provideLoginRequest(…, loginPresenter)
presentation.login.request.LoginRequest is injected at
mobileui.login.di.LoginActivityModule.provideLoginPresenter(…, loginRequest)
mobileui.login.LoginPresenter is injected at
mobileui.login.LoginFragment.loginPresenter

这是我收到错误的下面的模块

@Module
class LoginActivityModule {
@Reusable
@Provides
fun provideLoginPresenter(loginRequest: LoginRequest): LoginPresenter {
return LoginPresenterImp(loginRequest)
}

@Reusable
@Provides
fun provideLoginResponseListener(loginRequest: LoginRequest): LoginResponseListener {
LoginPresenterImp(loginRequest)
}

@Reusable
@Provides
fun provideLoginRequest(loginUser: LoginUser,
loginPresenter: LoginResponseListener): LoginRequest {
return LoginRequestImp(loginUser, loginPresenter)
}
}

我的 LoginPresenterImp 实现了 LoginResponseListener,我想将它传递给 LoginRequestImp 类,这样我就可以将它用作回调。

class LoginPresenterImp(private val loginRequest: LoginRequest) :
BasePresenterImp<LoginView>(),
LoginPresenter,
LoginResponseListener {
}

loginResponseListener 在这里传递:

class LoginRequestImp(
private val loginUser: LoginUser,
private val loginResponseListener: LoginResponseListener)
: LoginRequest {
}

非常感谢,

最佳答案

作为Ayush评论中描述:

You need LoginResponseListener to create LoginRequest and you need LoginRequest to create LoginResponseListener. So, you are getting the error.

When you are creating LoginRequest in LoginRequestImp(loginUser, loginPresenter), loginPresenter is a parameter to the constructor of type LoginResponseListener. You should try to eliminate this dependency. May be you can set the listener later from the presenter

在这些评论之间的回复中:

LoginRequest has been created in provideLoginRequest

但这就是正在发生的事情:

  1. 您的 LoginFragment 尝试注入(inject) LoginPresenter。
  2. 在注入(inject) LoginPresenter 之前,您需要创建一个 LoginRequest。
  3. 在创建 LoginRequest 之前,您需要一个 LoginUser 和一个 LoginRequestListener。
  4. 在创建 LoginRequestListener(已作为 LoginPresenterImpl 实现)之前,您需要一个 LoginRequest。
  5. 您正在创建 LoginRequest,因此 Dagger 放弃并正确报告循环引用。

重申一下:即使您使用接口(interface)正确设置了绑定(bind),Dagger 也无法创建它们中的任何一个,因为要调用其中一个构造函数,它必须创建另一个构造函数。这不是 Dagger 的问题:如果类 A 的构造函数采用 B 的实例,而类 B 的构造函数采用 A 的实例,那么在尊重它们的构造函数参数的同时,您也无法手动构造它们中的任何一个。


正如 Ayush 所建议的,不要让 LoginRequest 注入(inject) LoginResponseListener。相反,创建一个类似 setLoginResponseListener 的方法,LoginPresenterImp 可以调用它。我也推荐这种方法,部分原因是 @Reusable has weaker semantics than you want : 您要绝对确保充当您的 LoginPresenter 的 LoginPresenterImp 实例与充当 LoginResponseListener 的实例相同。

作为替代方案,您可以注入(inject) Provider<LoginPresenter>而不是 LoginResponseListener ,并更改 LoginRequestImp 以接受 Provider。 (您也可以注入(inject)一个 Provider<LoginResponseListener> ,但如果您希望 LoginResponseListener 与您的 LoginPresenter 实例相同,则不应显式调用 LoginPresenterImp 构造函数。您最好切换到 @Binds,或者在至少让你的 @Provides 方法注入(inject) LoginPresenter。)你被允许注入(inject)一个提供者,因为 a Provider<T> is automatically bound for every class <T> that Dagger knows how to provide ,它解决了你的问题,因为 Dagger 可以传递 Provider<T>无需尝试创建 T .即使您将绑定(bind)保留为 @Reusable,这在技术上似乎也有效, 但在多线程环境中 @Reusable不会保证您始终收到与 LoginPresenter 相同的 LoginRequestListener 实例,或者您会收到每个 LoginFragment 的新 LoginPresenter。如果你想保证这一点,你可以查看custom scopes .

关于android - 尝试使用 Dagger 解决依赖循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54009736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com