Hilt는 일반적으로 다음과 같이 생성자 주입 방식을 사용한다.
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
@Inject lateinit var analytics: AnalyticsAdapter
...
}
class AnalyticsAdapter @Inject constructor(
private val service: AnalyticsService
) { ... }
그러나 Hilt에서 생성자 주입을 할 수 없는 경우 Hilt 모듈을 만들어서 종속성을 주입해야 하며, 이 때 상황에 따라 @Provides와 @Binds 어노테이션을 사용할 수 있다.
@Provides를 사용하여 인스턴스 주입
Room이나 Retrofit, OkHttpClient등의 외부 라이브러리에서 제공되는 클래스이거나, 빌더 패턴으로 인스턴스를 생성해야 하는 경우 역시 생성자 주입이 불가능하고, 이럴 때 @Provides 어노테이션을 사용한다.
이 경우 함수 리턴 타입에 따라 어떤 타입의 인스턴스를 제공하는지 Hilt에 알려주고, 매개변수의 경우 해당 유형의 종속 항목을, 본문의 경우 해당 유형의 인스턴스를 제공하는 방법을 Hilt에 제공한다.
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {
@Provides
fun provideAnalyticsService(
// Potential dependencies of this type //
): AnalyticsService { // 제공할 인스턴스의 타입
return Retrofit.Builder() // 인스턴스 제공 방법, 주입해야 할 때 마다 다음 함수를 실행한다.
.baseUrl("https://example.com")
.build()
.create(AnalyticsService::class.java)
}
}
@Binds를 사용하여 인스턴스 주입
interface 역시 생성자를 주입할 수 없기 때문에 @Binds 어노테이션을 지정한 추상함수를 생성하여 Hilt에 알려주어야 한다.
이 때 함수 리턴 타입은 어떤 인터페이스의 인스턴스를 제공하는지 알려주며, 함수 매개변수는 제공할 구현체(implementation)를 알려준다.
interface AnalyticsService {
fun analyticsMethods()
}
// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
class AnalyticsServiceImpl @Inject constructor(
...
) : AnalyticsService { ... }
@Module
@InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {
@Binds
abstract fun bindAnalyticsService(
analyticsServiceImpl: AnalyticsServiceImpl // 매개변수로 구현체를 Hilt에 알려준다.
): AnalyticsService // 리턴 타입으로 제공할 인터페이스를 알려준다.
}
@Qualifier를 사용하여 동일한 유형의 리턴 타입에 대한 구분
외에 복수의 동일한 유형을 처리해야할 경우가 존재한다.
예를 들어 OkHttpClient를 사용할 때, 상황에 맞게 다른 Interceptor를 연결해주어야 하는 경우나, Retrofit2을 사용할 때 여러개의 BaseUrl을 사용해야 할 경우가 있다.
이 때 다음과 같이 @Qualifier 어노테이션을 사용하여 annotaion class를 작성하여 구분할 수 있다.
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherInterceptorOkHttpClient
위를 활용해 다음과 같이 동일한 리턴 타입(OkHttpClient)을 가진 경우를 처리할 수 있다.
@Module
@InstallIn(ApplicationComponent::class)
object NetworkModule {
@AuthInterceptorOkHttpClient
@Provides
fun provideAuthInterceptorOkHttpClient(
authInterceptor: AuthInterceptor
): OkHttpClient { // 리턴 타입이 OkHttpClient
return OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.build()
}
@OtherInterceptorOkHttpClient
@Provides
fun provideOtherInterceptorOkHttpClient(
otherInterceptor: OtherInterceptor
): OkHttpClient { // 리턴 타입이 OkHttpClient
return OkHttpClient.Builder()
.addInterceptor(otherInterceptor)
.build()
}
}
Reference:
https://developer.android.com/training/dependency-injection/hilt-android#hilt-modules
Hilt를 사용한 종속 항목 삽입 | Android 개발자 | Android Developers
Hilt를 사용한 종속 항목 삽입 Hilt는 프로젝트에서 수동 종속 항목 삽입을 실행하는 상용구를 줄이는 Android용 종속 항목 삽입 라이브러리입니다. 수동 종속 항목 삽입을 실행하려면 모든 클래스
developer.android.com
'Android > Architecture' 카테고리의 다른 글
안드로이드 프로젝트 Multi Module로 빌드시간 줄이기 (data, repository 계층 분리) (0) | 2022.05.08 |
---|---|
Android MVVM + DI(Hilt) 적용하기 (0) | 2022.03.21 |
WorkManager에 Hilt를 이용하여 의존성 주입하기 (0) | 2022.03.15 |
DataBinding vs ViewBinding (0) | 2021.11.20 |
Android - State Pattern (0) | 2021.11.13 |