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)@Moduleobject 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)@Moduleabstract 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.