안드로이드 개발을 하다 보면, @Inject, @HiltAndroidApp, @Module 같은 어노테이션들을 한 번쯤은 마주치게 됩니다. 익숙한 문법으로 느껴질 수 있지만, 과연 내가 프로젝트를 할 때 Hilt와 의존성 주입(Dependency Injection)의 개념을 제대로 이해하고 있었던 걸까...? 라는 생각이 들게 되어 이번 포스팅에서는 Hilt와 DI의 기본 개념부터 실제 프로젝트에서 어떻게 활용할 수 있는지, 그리고 주의할 점까지 정리해 보았습니다.
1. 의존성 주입이란?
DI는 객체 간의 의존 관계를 외부에서 주입해 주는 디자인 패턴입니다.
쉽게 말하면, 필요한 객체를 직접 생성하지 않고 외부에서 주입받는 방식이라고 할 수 있습니다.
class UserRepository
class UserViewModel(private val repository: UserRepository)
이렇게 구성된 코드가 있다면, UserViewModel은 UserRepository에 의존하지만, 직접 생성하지 않고 외부에서 주입받습니다.
2. Hilt?
Hilt는 Google이 공식적으로 제공하는 안드로이드 DI 프레임워크입니다.
Dagger 기반으로 작동하며, 안드로이드 컴포넌트에 최적화되어 있어 간편하고 안정적인 DI 환경을 제공합니다.
- @HiltAndroidApp, @AndroidEntryPoint 등 간단한 어노테이션만으로 DI 구성 가능
- Application, Activity, Fragment, ViewModel 등 라이프사이클 컴포넌트 지원
- 테스트 용이성 및 유지보수성 향상
3. Hilt 사용법
@HiltAndroidApp
class MyApp : Application()
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var viewModel: MainViewModel
}
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideRepository(): Repository = RepositoryImpl()
}
@HiltViewModel
class MainViewModel @Inject constructor(
private val repository: Repository
) : ViewModel() {
// ...
}
이처럼 설정하면, MainActivity에서는 별도의 생성 없이 viewModel을 사용할 수 있습니다.
아래에는 프로젝트에서 자주 사용한 어노테이션들을 정리해 보았습니다.
- @HiltAndroidApp: Hilt DI를 앱 전역에서 사용할 수 있도록 Application에 붙이는 어노테이션
- @AndroidEntryPoint: Hilt 의존성을 주입받을 Android 컴포넌트에 붙이는 어노테이션
- @Inject: Hilt가 생성자나 필드에 의존성을 자동으로 주입하도록 표시
- @Module: 의존성을 생성하거나 바인딩하는 메서드를 모아두는 클래스에 붙이는 어노테이션
- @Provides: 특정 객체를 생성해서 제공하는 팩토리 메서드에 붙이는 어노테이션
- @Binds: 구현체와 인터페이스를 바인딩할 때 사용하는 추상 메서드에 붙이는 어노테이션
- @InstallIn: 모듈이 설치될 Hilt 컴포넌트의 범위를 지정하는 어노테이션
- @HiltViewModel: ViewModel에 의존성 주입을 가능하게 하는 어노테이션
4. Hitl 사용할 때의 주의점
- 무분별한 의존성 주입은 오히려 테스트와 유지보수를 어렵게 만들 수 있음.
- 의 존성이 깊어질수록 구조가 복잡해지고, 어디에서 어떤 객체가 주입되는지 추적하기 어려워질 수 있음.
- Hilt는 어노테이션 프로세서를 사용하기 때문에, 프로젝트 규모가 커지면 빌드 시간이 증가할 수 있습니다.
5. 마무리
의존성 주입은 단순히 편리함을 위한 수단이 아닙니다. 프로젝트의 구조를 유연하고 확장성 있게 설계할 수 있도록 도와주는 핵심적인 설계 패턴입니다. Hilt는 이러한 DI를 안드로이드 환경에서 보다 쉽게 구현할 수 있도록 돕는 강력한 도구라 생각합니다. 하지만 그만큼 내부 동작 원리와 목적에 대한 명확한 이해 없이 사용하게 되면, 오히려 프로젝트의 복잡도를 증가시킬 수 있습니다.
다음 포스팅에서는 DI에서 자주 사용되는 디자인 패턴에 대해 포스팅하겠습니다. 🚀
'안드로이드' 카테고리의 다른 글
[Android] 에러는 없는데 빌드가 안될 때 해결 팁 3가지 (1) | 2025.06.24 |
---|---|
[Android] - 라이브러리 없이 캔들 차트를 구현해보자!! (0) | 2025.04.29 |
[Android] - dependency api에 관하여.... (0) | 2025.04.15 |
[Android] - OkHttp VS Retrofit (0) | 2025.04.01 |
[Android] - SSE로 실시간 통신하기! (0) | 2025.04.01 |