Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hilt - Dependency cycle crash

If I just use the AuthRepository class in a single UseCase it's fine. However, if I try to use it in both AuthUseCase and RefreshTokenUseCase as in the example, I get an error.

Any suggestions other than using Lazy<> ?

Any help will be appreciated.

-

Error

-

App_HiltComponents.java:139: error: [Dagger/DependencyCycle] Found a dependency cycle:
  public abstract static class SingletonC implements App_GeneratedInjector,
                         ^
      AppRepository is injected at
          RefreshTokenTokenUseCase(authRepository)
      RefreshTokenTokenUseCase is injected at
          AppAuthenticator(refreshTokenTokenUseCase)
          ......
          ...
          ..
      AuthUseCase(authRepository)
      AuthUseCase is injected at
          MainViewModel(authUseCase, …)
               MainViewModel is injected at
          MainViewModel_HiltModules.BindsModule.binds(vm)

My Code

-

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Singleton
    @Provides
    fun provideRetrofit(): Retrofit =
        Retrofit.Builder()
            .baseUrl(Data.url)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
}

@Module
@InstallIn(SingletonComponent::class)
object ApiModule {

    @Singleton
    @Provides
    fun provideAuthAPI(
        retrofit: Retrofit
    ): AuthAPI = retrofit.create(AuthAPI::class.java)
}


@Singleton
class AuthRepository @Inject constructor(
    private var authAPI: AuthAPI,
) {

}

@Singleton
class AuthUseCase @Inject constructor(
    private val authRepository: AuthRepository
) : UseCase<Response?, AuthUseCase.Params>() { 

}

@Singleton
class RefreshTokenUseCase @Inject constructor(
    private val authRepository: AuthRepository
) : UseCase<String?, RefreshTokenUseCase.Params>() { 

}
like image 337
enjektor0 Avatar asked Dec 21 '25 08:12

enjektor0


1 Answers

You can use Provider<T> instead of Lazy and than call .get() on it.

@Singleton
class RefreshTokenUseCase @Inject constructor(
    private val authRepositoryProvider: Provider<AuthRepository>
) : UseCase<String?, RefreshTokenUseCase.Params>() { 
    fun getRefreshToken() = authRepositoryProvider.get().getRefreshToken() //example of usage
}

This means RefreshTokenUseCase will be created before AuthRepository is created and later on it will receive singleton AuthRepository instance it needs. For more complete explanation check this SO post.

like image 75
Torima Avatar answered Dec 22 '25 21:12

Torima



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!