@@@@ 골뱅이
안드로이드에서 많이 사용하는 DI 라이브러리인 Hilt에서 자주 사용하는 Annotation 정리 및 사용 예시
Application 클래스에 붙이며, Hilt가 애플리케이션의 의존성 그래프를 생성할 수 있도록 해준다. 이 어노테이션을 추가하면 Hilt가 애플리케이션의 전반적인 라이프사이클을 관리하게 된다.
@HiltAndroidApp
class MyApplication : Application()
Activity, Fragment, Service, View, BroadcastReceiver 등에 붙이며, Hilt가 해당 클래스에서 의존성 주입을 가능하게 해준다. 이 어노테이션을 붙이면 해당 클래스에서 @Inject를 통해 의존성을 주입받을 수 있다.
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
...
}
생성자나 필드에 붙여 Hilt가 해당 클래스 또는 필드의 인스턴스를 주입하도록 한다. 생성자 주입과 필드 주입 모두 가능하며, 일반적으로는 생성자 주입이 권장된다.
@Inject lateinit var networkManager: NetworkManager // 필드 주입
class MyViewModel @Inject constructor(
.... // 생성자 주입
)
Hilt 모듈을 정의하기 위해 사용된다. 모듈은 의존성 그래프에 추가할 의존성을 제공하며, Hilt는 @Module이 붙은 클래스를 통해 의존성을 제공한다.
보통 @InstallIn 와 같이 사용한다.
@Module
@InstallIn(SingletonComponent::class)
object LocalDataModule {
...
}
모듈 클래스에 @Module과 함께 붙여 사용하는 어노테이션으로, 모듈의 라이프사이클 범위를 지정한다. 예를 들어 @SingletonComponent에 설치하면 애플리케이션 전체에 의존성이 유지된다.
@Module
@InstallIn(SingletonComponent::class)
object LocalDataModule {
...
}
위에서 SingletonComponent로 선언 시 애플리케이션 스코프에 해당 모듈이 생성된다.
@Module 내부의 메소드에 붙이며, 해당 메소드가 의존성을 제공할 수 있도록 한다. 이 메서드를 통해 특정 타입의 인스턴스를 생성하여 의존성 그래프에 추가할 수 있다.
@Module
@InstallIn(SingletonComponent::class)
object LocalDataModule {
@Provides
fun provideLocalData(
@ApplicationContext context: Context
): LocalDataSource {
return LocalDataSourceImpl(
context = context
)
}
}
위에서 @Provides만 사용 시 사용될 때 마다 인스턴스를 새로 생성한다.
Hilt의 @Provides나 클래스 레벨에 붙여 인스턴스가 싱글톤으로 관리되도록 합니다. @SingletonComponent와 함께 사용하여 애플리케이션 전역에서 인스턴스가 하나만 생성되도록 할 수 있다.
@Module
@InstallIn(SingletonComponent::class)
object LocalDataModule {
@Provides
@Singleton
fun provideLocalData(
@ApplicationContext context: Context
): LocalDataSource {
return LocalDataSourceImpl(
context = context
)
}
}
@Singleton 사용 시 해당 인스턴스는 객체를 한 번만 생성하고, 이후에는 이미 생성된 인스턴스를 재사용한다.
@Module 내부에 사용하여 인터페이스를 구현체에 바인딩할 때 사용한다. 인터페이스와 이를 구현하는 클래스 간의 매핑을 정의할 수 있다.
@Module
@InstallIn(SingletonComponent::class)
interface RepositoryModule {
@Binds
fun bindMyRepository(
impl: DefaultMyRepository // 실제 구현체
): MyRepository // 인터페이스
}
위 예시처럼 Repository나 DataSource, 등 인터페이스와 실제 구현체를 연결 해주는 역할을 한다.
동일한 타입의 서로 다른 인스턴스를 구분하기 위해 사용된다. 커스텀 Qualifier를 만들어 @Inject 또는 @Provides와 함께 사용할 수 있다.
enum class AppDispatcher {
Default,
IO,
Main
}
@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class Dispatcher(val dispatcher: AppDispatcher)
//
@Dispatcher(AppDispatcher.IO)
@Provides
fun provideIoDispatcher(): CoroutineDispatcher = Dispatchers.IO
// 사용 예시
class MyRepository @Inject constructor(
@Dispatcher(AppDispatcher.IO) private val ioDispatcher: CoroutineDispatcher
) {
...
}
ViewModel 클래스에 붙이며, @Inject 생성자와 함께 사용하여 ViewModel에 의존성을 주입할 수 있다.
이 어노테이션들은 Hilt의 의존성 주입 시스템을 구성하는 중요한 요소들이며, 주입 위치나 범위에 따라 적절하게 사용하여야 한다.
@HiltViewModel
class MainViewModel @Inject constructor(
private val myRepository: MyRepository
)