Hilt (의존성 주입) (1)
Hilt 란?
Android에서 DI(의존성 주입 또는 종속 항목 삽입)을 사용할 수 있게 해주며, 이를 통해 컴포넌트가 각 구성 요소의 생명주기와 맞물려 작동할 수 있도록 생명주기의 범위를 설정해주는 프레임워크 중 하나이다.
DI란?
의존성 주입 또는 종속 항목 삽입으로 불리며, 프로그래밍에서 널리 사용되는 기법이다. 객체의 생성과 관심사 분리에 사용되는 방법으로, 어떤 서비스를 이용할 때 이를 내부가 아닌 외부에서 생성하여 해당 서비스를 이용할 수 있도록 해주는 것이다.
DI를 사용할 때의 장점
결합도 감소 : 객체 간의 결합도가 낮아진다. 객체는 의존성에 대해 구체적을 알 필요가 없으며, 외부에서 필요한 의존성을 주입받기 때문에 변경에 용이하다.
ex) Car 객체는 Engine 객체의 구현에 의존하지 않고, 외부에서 어떤 Engine이 주입되든 사용할 수 있음
유연성 향상 : 의존성을 외부에서 주입하기 때문에 코드를 쉽게 변경할 수 있다. 특정 의존성을 변경하거나 새로운 의존성을 추가하기 위해 객체를 수정할 필요가 없다.
ex) 테스트 시 MockEngine을 주입하여 실제 엔지 없이도 Car 객체를 테스트할 수 있다.
테스트 용이 : DI를 통해 객체의 의존성을 쉽게 모의 객체(Mock Object)로 교체할 수 있어 단위 테스트가 용이하다. 외부로부터 주입된 의존성은 테스트 환경에서 임의의 객체로 대체 가능하다.
ex) Car 객체를 테스트 할 때 실제 엔진 객체 대신 가짜 엔진을 주입해 테스트할 수 있다.
재사용성 증가 : DI를 사용하면 같은 클래스가 다양한 의존성을 주입받아 여러 곳에서 재사용될 수 있다. 의존성 변경에 따른 코드 수정 없이 다양한 의존성을 주입하여 다른 환경에서 재사용이 가능하다.
Boilerplate code 감소 : 자주 반복적으로 작성해야하는 코드를 뜻하는 Boilerplate code를 감소 시킬 수 있다.
Hilt를 사용하는 이유
특징 | 설명 |
간편한 의존성 주입 설정 | Dagger2에 비해 간결한 구문을 사용해 의존성 주입을 설정할 수 있고, 필용한 의존성을 컴포넌트 간에 주입하는 과정을 자동화함. |
Android에 특화된 컴포넌트 제공 | Activity, Fragment, ViewModel 등 Android 구성 요소에 맞춘 의존성 주입을 지원, 이를 통해 생명주기와 잘 맞물리는 의존성 관리가 가능 |
테스트 용이성 | 의존성 주입을 사용한 클래스에 대해 테스트를 쉽게 작성할 수 있도록 지원 |
모듈화된 코드 | 의존성을 모듈 단위로 관리할 수 있어 코드의 재사용성을 높이고, 유지 보수를 용이하게 만듬 |
Hilt 컴포넌트의 생명주기
구성 요소의 범위
Hilt의 모든 바인딩은 범위가 지정되지 않는다. 즉, 앱이 바인딩을 요청할 때마다 Hilt는 필요한 유형의 새 인스턴스를 만든다.
그러나, 바인딩이 특정 구성 요소로 범위가 지정되도록 허용할 수 있다. Hilt는 바인딩이 범위가 지정된 구성 요소의 인스턴스당 한 번만 범위가 지정된 바인딩을 만들고 해당 바인딩에 대한 모든 요청은 동일한 인스턴스를 공유한다.
구성요소의 계층 구조
구성요소에 모듈을 설치하면 이 구성요소의 다른 결합 또는 구성요소 계층 구조에서 그 아래에 있는 하위 구성요소의 다른 결합의 종속 항목으로 설치된 모듈의 결합에 액세스 할 수 있다.
Hilt의 주요 컴포넌트
컴포넌트 | 생명주기 관계 |
@HiltAndroidApp | Application 클래스에서 사용하며, 애플리케이션 전체의 생명주기 동안 살아있는 의존성을 괸리 애플리케이션 수준의 의존성 (네트워크 클라이언트, 데이터베이스 등)을 제공할 때 유리 |
@AndroidEntryPoint | Activity, Service, View, Fragment 와 같은 Android 구성 요소에서 사용하며, 해당 구성 요소에 의존성을 주입 각 구성 요소의 생명주기를 인식하여 의존성을 해당 구성 요소의 생명주기 동안만 유지 Hilt 컴포넌트의 생명 주기 참고 |
스코프 어노테이션 | 각 구성 요소의 생명주기에 맞춰 스코프를 지정할 수 있는 어노테이션을 제공 해당 스코프들은 의존성의 수명을 제어하는 데 사용 구성 요소의 범위 부분 참고 |
@HiltViewModel | ViewModel과도 쉽게 통합 가능 ViewModel에 해당 어노테이션을 사용하여 필요한 의존성 주입 이때 Hilt는 ViewModel의 생명주기에 맞춰 의존성을 관리 |
Android에서 사용하기
1. 의존성 추가
dependencies {
implementation "com.google.dagger:hilt-android:2.x"
kapt "com.google.dagger:hilt-android-compiler:2.x"
}
2. Application 클래스에서 Hilt 초기화
@HiltAndroidApp
class MyApplication : Application()
3. Acitivity나 Fragment에서 Hilt 사용
@AndroidEntryPoint
class MyActivity : AppCompatActivity() {
@Inject lateinit var myDependency: MyDependency
}
4. 모듈 정의
@Module
@InstallIn(SingletonComponent::class)
object MyModule {
@Provides
fun provideMyDependency(): MyDependency {
return MyDependency()
}
}
ViewModel을 사용하는 경우
1. 프로젝트 레벨의 종속성 추가
buildscript {
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.x"
}
}
2. 모듈 레벨의 종속성 추가
plugins {
id 'com.android.application'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
dependencies {
implementation "com.google.dagger:hilt-android:2.x"
kapt "com.google.dagger:hilt-android-compiler:2.x"
// ViewModel 관련 종속성
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
}
3.ViewModel에서 사용
@HiltViewModel
class MyViewModel @Inject constructor(
private val repository: MyRepository
) : ViewModel() {
// ViewModel의 로직
val data = liveData {
emit(repository.getData())
}
}
참고 자료
[Android] Hilt 사용하기
DI는 프로그래밍에 널리 사용되는 방식으로 객체의 생성과 사용의 관심을 분리하는 것이다. 다시말하면 클라이언트에서 어떤 서비스를 이용할 때 이를 외부에서 생성하여 해당 서비스를 사용할
velog.io
Hilt를 사용한 종속 항목 삽입 | Android Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. Hilt를 사용한 종속 항목 삽입 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Hilt는 프로젝트에서 종속
developer.android.com