I've been exploring HILT documentation and came across the information that scoping a binding incurs costs in both generated code size and runtime performance. The general guideline is to scope a binding only if it's necessary for the correctness of the code.
I'm seeking clarification on when it is appropriate to scope dependencies. To illustrate, I have two examples:
Example 1: Networking Retrofit Dependencies
I have my networking Retrofit dependencies installed in SingletonComponent. Should I consider scoping them, and if so, what factors should I take into account?
@InstallIn(SingletonComponent::class)
@Module
object RetrofitModule {
private const val BASE_URL = "xyz"
@Provides
fun provideLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
@Provides
fun provideOkHttpClient(loggingInterceptor: HttpLoggingInterceptor): OkHttpClient =
OkHttpClient.Builder()
.addInterceptor(interceptor = loggingInterceptor)
.build()
@Provides
fun provideRetrofitInstance(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
Example 2: Mappers and Repository Dependencies in ViewModelComponent
For mappers and repository dependencies installed in ViewModelComponent, should scoping be applied? What considerations are important in this context?
@InstallIn(ViewModelComponent::class)
@Module
abstract class DataModule {
companion object {
@Provides
fun provideCountMapper(): CountMapper = CountMapper()
@Provides
fun provideCountListMapper(countMapper: CountMapper): CountListMapper =
CountListMapper(countMapper = countMapper)
@Provides
fun providesCoroutineDispatcher(): CoroutineDispatcher = Dispatchers.IO
}
@Binds
abstract fun bindXYZRepository(xyzRepositoryImpl: XYZRepositoryImpl): XYZRepository
}
Additionally, is it accurate to state that scoping a stateless object generally doesn't provide significant benefits and may introduce inefficiencies? Conversely, scoping a stateful object ensures consistent behavior and data management within its lifecycle.