Hilt 라이브러리를 이용해 의존성을 주입하는 경우에 Module에서
abstract class에는 @Binds 어노테이션이,
object에는 @Provides 키워드가 붙게 되는데 어떤 이유에서인지 알아보겠습니다.
작성한 예시 코드를 보여드리며 설명하겠습니다.
@Module
@InstallIn(SingletonComponent::class)
abstract class DataModule {
@Binds
abstract fun bindsDataStoreDataSource(
dataStoreDataSource: DataStoreDataSourceImpl
): DataStoreDataSource
@Binds
abstract fun bindsDataStoreRepository(
dataStoreRepository: DataStoreRepositoryImpl
): DataStoreRepository
@Binds
abstract fun bindsUserDataSource(
authDataSource: UserDataSourceImpl
): UserDataSource
@Binds
abstract fun bindsUserRepository(
authRepository: UserRepositoryImpl
): UserRepository
...
}
@Binds는 인터페이스와 구현체 간의 관계를 바인딩하기 위해 사용됩니다.DataStoreDataSource, DataStoreRepository, UserDataSource, UserRepository는 인터페이스, 그리고 DataStoreDataSourceImpl, DataStoreRepositoryImpl, UserDataSourceImpl, UserRepositoryImpl는 구현체입니다.Hilt는 자동으로 인터페이스의 구현체를 의존성 주입에 사용할 수 있도록 설정합니다.@Binds를 사용하는 모듈은 반드시 abstract 키워드를 사용해야 합니다.@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
@Singleton
fun providesOkHttpClient(
@ApplicationContext context: Context,
tokenProvider: () -> String
): OkHttpClient {
val builder = OkHttpClient.Builder()
.addInterceptor(AuthInterceptor(tokenProvider))
.addNetworkInterceptor(
HttpLoggingInterceptor().apply {
if (BuildConfig.DEBUG) {
level = HttpLoggingInterceptor.Level.BODY
}
}
)
if (BuildConfig.DEBUG) {
builder.addNetworkInterceptor(ChuckerInterceptor(context))
}
return builder.build()
}
@Provides
@Singleton
fun providesRetrofit(okHttpClient: OkHttpClient): Retrofit =
Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BuildConfig.BASE_URL)
.addCallAdapterFactory(ApiResultCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
@Provides
@Singleton
fun providesUserService(retrofit: Retrofit): UserService =
retrofit.create(UserService::class.java)
...
}
@Provides는 복잡한 로직을 포함한 객체를 생성하거나, 외부 라이브러리에서 제공하는 객체를 의존성으로 주입해야 할 때 사용됩니다.OkHttpClient, Retrofit, 그리고 UserService 는 간단한 생성자 호출만으로 생성되지 않으며, 추가 설정이나 생성 과정이 필요합니다.OkHttpClient의 경우, Interceptor, Logging 등을 추가로 설정하며 객체를 생성합니다.Retrofit은 OkHttpClient와 함께 특정 설정을 추가해 객체를 만듭니다.| 특징 | DataModule (@Binds) | NetworkModule (@Provides) |
|---|---|---|
| 사용 목적 | 인터페이스와 구현체 연결 | 복잡한 로직을 포함한 객체 생성 |
| 메서드 타입 | 추상 메서드 (abstract method) | 구체적 메서드 (concrete method) |
| 코드 구조 | 단순하며, 구현체와 인터페이스를 연결하는 데 적합 | 복잡한 로직이나 외부 라이브러리 객체 생성을 지원 |
| 객체 생성 방식 | Hilt가 생성자를 호출해 자동으로 생성 | 메서드 내에서 객체 생성 로직을 직접 작성 |
| 성능 및 효율성 | 더 효율적 (추가 로직이 없음) | 약간의 오버헤드가 발생 |
| 사용 사례 | Repository, DataSource 같은 단순 구현체와 인터페이스의 연결 | OkHttpClient, Retrofit, 외부 라이브러리 객체 생성 |
Repository, DataSource 같은 내부 객체 간의 바인딩.Retrofit, OkHttpClient 같은 네트워크 관련 객체 생성.