JungHoon
JungHoon

Reputation: 302

Dependency injection at Singleton instance with hilt-android

Have a question while using hilt-android.
And I'm making some network module with retrofit, and handling with hilt.

@InstallIn(SingletonComponent::class)
object NetworkModule {    

    @Singleton
    @Provides
    fun provideBaseRetrofit(
      @BaseHttpClient
      client: OkHttpClient): Retrofit {
        val builder =
          Retrofit.Builder()
            .baseUrl(URL.Server.baseURL)
            .addCallAdapterFactory(ApiResponseCallAdapterFactory.create())
            .addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
            .client(client)
            .build()
        
        return builder
    }

    @BaseHttpClient
    @Provides
    fun provideDefaultClient(
      @BaseRequestIntercept
      requestInterceptor: Interceptor,
      @BaseResponse
      responseInterceptor: Interceptor,
      @Logging
      logging: Interceptor): OkHttpClient {
        return DefaultHttpClient().newBuilder().apply {
            addInterceptor(requestInterceptor)
            addInterceptor(responseInterceptor)
            addInterceptor(logging)
        }.build()
    }
}

@Module
@InstallIn(SingletonComponent::class)
abstract class InterceptorModules {
    @BaseRequestIntercept
    @Binds
    abstract fun bindRequestInterceptor(request: RequestInterceptor): Interceptor
    
    @BaseResponse
    @Binds
    abstract fun bindResponseInterceptor(response: ResponseInterceptor): Interceptor
}

At this point, my question is, @singleton annotation.

At first, I attach singleton annotation to every single object, such as httpClient/requestInterceptor/responseInterceptor

However, the object's hashcode doesn't change even I remove annotation.
(Except retrofit, I remain singleton annotation to retrofit)

And my assume is, the singleton annotation only needs most upper instance.
like...

Intercept(not singleton) -> okhttp(not singleton) -> retrofit (singleton)

Why I though like this, retrofit is a singleton instance. Instance will not change so that It'll not make any other dependency object while application is living.

But I have no idea that my assume is correct, so I ask you guys...

Every example what I refer to, always attach @singleton annotation to every single provides class..

Is my approach wrong?

Thanks in advance!!!

Upvotes: 0

Views: 1331

Answers (1)

TheLibrarian
TheLibrarian

Reputation: 1888

Your assumption is correct. Since Retrofit is Singleton and Retrofit is the only thing that needs Intercept/OkHttp there is only one instantiation of those. You can even test it the other way around - have everything else @Singleton and then you would see that Intercept/OkHttp hashCode is the same but Retrofit changes.

To answer the underlying question - should every component there(Intercept/OkHttp) have @Singleton?

In general, it depends only on what you need it to do. Here you are not doing a mistake having or not having it there because Retrofit already takes care of it and it works but... this way you are implicitly relying on them being scoped by some other dependency which could cause issues in the future where you would count them as singleton even though they are not defined/scoped as such.

Upvotes: 1

Related Questions