Hovhannes
08/18/2021, 10:29 AM@Module
@InstallIn(SingletonComponent::class)
abstract class AppModule {
companion object {
@Singleton
@Provides
fun provideRemoteDataSource(): RemoteDataSource {
return RemoteDataSource()
}
@Singleton
@Provides
fun provideUserApi(
remoteDataSource: RemoteDataSource,
): UserApi {
return remoteDataSource.buildTokenApi()
}
@Provides
fun provideAuthRepository(authApi: AuthApi): AuthRepository {
return AuthRepository(authApi)
}
@Provides
fun provideUserRepository(userApi: UserApi): UserRepository {
return UserRepository(userApi)
}
}
@Binds
@Singleton
abstract fun bindsRemoteDataSource(authRepository: AuthRepository): AuthApi
}
class AuthRepository @Inject constructor(private val api: AuthApi) : BaseRepository(api) {....}
Arun
08/18/2021, 10:52 AM@binds
should be a subclass of the method return type
is AuthRepository
subclass of AuthApi
?
@Binds
@Singleton
abstract fun bindsRemoteDataSource(authRepository: AuthRepository): AuthApi
Hovhannes
08/18/2021, 11:14 AMAuthRepository
is not subclass of AuthApi
. I can show Authapi.
interface AuthApi : BaseApi {
@FormUrlEncoded
@PUT("{PartnerId}/LoginClient")
suspend fun login(
@Field("name") name:String,
@Path("partnerId") partnerId:String,
@Field("Password") password: String
): LoginResponse
}
Arun
08/18/2021, 11:23 AMbindsRemoteDataSource(authRepository: AuthRepository): AuthApi
you are asking dagger to bind AuthApi
interface to authRepository
which is an invalid connection.
Did you mean to bind AuthApi
instead? I assume this is for Retrofit, instead what you can do is to write a @Provides method similar to ones you have already written and return the instance created with Retrofit builder for example like this
@Provides fun authApi() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("<https://api.github.com/>")
.build();
return retrofit.create(AuthApi.class);
}
Hovhannes
08/18/2021, 11:38 AMArun
08/18/2021, 11:41 AMAuthApi cannot be provided without an @Provides-annotated methodDagger is basically saying it can't create instance of AuthApi and neither there is a @Provides method to help create one.
Hovhannes
08/18/2021, 11:46 AM@Provides fun authApi() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("<https://api.github.com/>")
.build();
return retrofit.create(AuthApi.class);
}
Arun
08/18/2021, 11:56 AM@Provides fun authApi(@Named("baseUrl") baseUrl : String) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.build();
return retrofit.create(AuthApi.class);
}
Then create another binding for baseUrl like done here https://github.com/chrisbanes/tivi/blob/main/app/src/main/java/app/tivi/inject/AppModule.kt#L76
Will the API url change at runtime? If so you can return a retrofit builder instead and build api instance at runtime like
@Provides fun retrofitBuilder() : Retrofit.Builder() {
return Retrofit.Builder().apply {
// any other config
}
}
///
class AuthRepository @Inject constructor(private val apiBuilder: Retrofit.Builder) : BaseRepository {
private val authApi by lazy {
apiBuilder.baseUrl("<url here>").build()
}
}
Hovhannes
08/18/2021, 12:47 PM