본문 바로가기
Android

Hilt: Android Dependency Injection 완벽 가이드

by 안될개발 2025. 2. 22.

Hilt: Android Dependency Injection 완벽 가이드

Hilt: Android Dependency Injection 완벽 가이드

Hilt는 Android에서 Dependency Injection(DI)을 간편하게 사용할 수 있도록 제공하는 라이브러리입니다. Dagger를 기반으로 하며, 코드의 복잡도를 줄이고 모듈화된 아키텍처를 구축하는 데 유용합니다.


1. Dependency Injection이란?

Dependency Injection(DI)은 객체 간의 의존성을 직접 생성하는 것이 아니라 외부에서 주입하는 디자인 패턴입니다. 이를 통해 코드의 유지보수성과 테스트 용이성을 높일 수 있습니다.

예제: 직접 의존성 주입하는 방식

class Engine {
    fun start() = "Engine Started"
}

class Car {
    private val engine = Engine()
    fun start() = engine.start()
}

위처럼 직접 객체를 생성하면, 엔진을 교체하거나 테스트하기 어려운 구조가 됩니다.

DI를 적용한 방식

class Car(private val engine: Engine) {
    fun start() = engine.start()
}

이제 Car 클래스는 Engine에 직접 의존하지 않고, 외부에서 주입받을 수 있습니다.


2. Hilt 설정 및 기본 사용법

2.1 프로젝트에 Hilt 추가하기

Gradle(프로젝트 수준)

classpath 'com.google.dagger:hilt-android-gradle-plugin:2.48'

Gradle(모듈 수준)

plugins {
    id 'com.google.dagger.hilt.android'
    id 'kotlin-kapt'
}

dependencies {
    implementation 'com.google.dagger:hilt-android:2.48'
    kapt 'com.google.dagger:hilt-compiler:2.48'
}

2.2 Application 클래스 설정

Hilt를 사용하려면 @HiltAndroidApp을 Application 클래스에 추가해야 합니다.

@HiltAndroidApp
class MyApplication : Application()

3. Hilt로 의존성 주입하기

3.1 모듈(Module) 생성

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Provides
    @Singleton
    fun provideEngine(): Engine {
        return Engine()
    }
}
  • @Module: Hilt에 제공할 의존성을 정의하는 클래스
  • @InstallIn(SingletonComponent::class): 애플리케이션 전체에서 유지되는 객체임을 명시
  • @Provides: Hilt가 이 객체를 관리하도록 함

3.2 ViewModel에서 사용하기

@HiltViewModel
class CarViewModel @Inject constructor(private val engine: Engine) : ViewModel() {
    fun startCar() = engine.start()
}
  • @HiltViewModel: Hilt가 ViewModel을 관리할 수 있도록 함
  • @Inject constructor(...): 필요한 의존성을 자동으로 주입

3.3 Activity에서 주입하기

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var carViewModel: CarViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        println(carViewModel.startCar())
    }
}
  • @AndroidEntryPoint: Hilt를 사용하는 Activity, Fragment 등에 필수 추가
  • @Inject lateinit var ...: Hilt가 ViewModel을 자동으로 주입

4. Hilt를 활용한 실전 예제

4.1 인터페이스를 활용한 DI

interface Engine {
    fun start(): String
}

class DieselEngine @Inject constructor() : Engine {
    override fun start() = "Diesel Engine Started"
}

@Module
@InstallIn(SingletonComponent::class)
object EngineModule {
    @Provides
    fun provideEngine(): Engine = DieselEngine()
}

위처럼 인터페이스를 활용하면, Engine의 구현체를 쉽게 변경할 수 있습니다.


5. 결론

Hilt를 활용하면 다음과 같은 이점을 얻을 수 있습니다:

✅ Boilerplate 코드 감소 ✅ 의존성 주입을 통한 테스트 용이성 향상 ✅ 모듈화를 통한 유지보수성 증가

Hilt를 활용하여 더 간결하고 유지보수하기 쉬운 Android 앱을 개발해보세요! 🚀