[Android] Hilt의 어노테이션

박상군·2024년 10월 30일
0

Dependency Injection

목록 보기
3/5
post-thumbnail

@@@@ 골뱅이

안드로이드에서 많이 사용하는 DI 라이브러리인 Hilt에서 자주 사용하는 Annotation 정리 및 사용 예시

1. @HiltAndroidApp

Application 클래스에 붙이며, Hilt가 애플리케이션의 의존성 그래프를 생성할 수 있도록 해준다. 이 어노테이션을 추가하면 Hilt가 애플리케이션의 전반적인 라이프사이클을 관리하게 된다.

@HiltAndroidApp
class MyApplication : Application()

2. @AndroidEntryPoint

Activity, Fragment, Service, View, BroadcastReceiver 등에 붙이며, Hilt가 해당 클래스에서 의존성 주입을 가능하게 해준다. 이 어노테이션을 붙이면 해당 클래스에서 @Inject를 통해 의존성을 주입받을 수 있다.

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
	...
}

3. @Inject

생성자나 필드에 붙여 Hilt가 해당 클래스 또는 필드의 인스턴스를 주입하도록 한다. 생성자 주입과 필드 주입 모두 가능하며, 일반적으로는 생성자 주입이 권장된다.

@Inject lateinit var networkManager: NetworkManager // 필드 주입

class MyViewModel @Inject constructor(
	.... // 생성자 주입
)

4. @Module

Hilt 모듈을 정의하기 위해 사용된다. 모듈은 의존성 그래프에 추가할 의존성을 제공하며, Hilt는 @Module이 붙은 클래스를 통해 의존성을 제공한다.
보통 @InstallIn 와 같이 사용한다.

@Module
@InstallIn(SingletonComponent::class)
object LocalDataModule {
	...
}

5. @InstallIn

모듈 클래스에 @Module과 함께 붙여 사용하는 어노테이션으로, 모듈의 라이프사이클 범위를 지정한다. 예를 들어 @SingletonComponent에 설치하면 애플리케이션 전체에 의존성이 유지된다.

@Module
@InstallIn(SingletonComponent::class)  
object LocalDataModule {
	...
}

위에서 SingletonComponent로 선언 시 애플리케이션 스코프에 해당 모듈이 생성된다.

6. @Provides

@Module 내부의 메소드에 붙이며, 해당 메소드가 의존성을 제공할 수 있도록 한다. 이 메서드를 통해 특정 타입의 인스턴스를 생성하여 의존성 그래프에 추가할 수 있다.

@Module
@InstallIn(SingletonComponent::class)
object LocalDataModule {
	@Provides
    fun provideLocalData(
        @ApplicationContext context: Context
    ): LocalDataSource {
        return LocalDataSourceImpl(
         	  context = context
        )
    }
}

위에서 @Provides만 사용 시 사용될 때 마다 인스턴스를 새로 생성한다.

7. @Singleton

Hilt의 @Provides나 클래스 레벨에 붙여 인스턴스가 싱글톤으로 관리되도록 합니다. @SingletonComponent와 함께 사용하여 애플리케이션 전역에서 인스턴스가 하나만 생성되도록 할 수 있다.

@Module
@InstallIn(SingletonComponent::class)
object LocalDataModule {
	@Provides
    @Singleton
    fun provideLocalData(
        @ApplicationContext context: Context
    ): LocalDataSource {
        return LocalDataSourceImpl(
         	  context = context
        )
    }
}

@Singleton 사용 시 해당 인스턴스는 객체를 한 번만 생성하고, 이후에는 이미 생성된 인스턴스를 재사용한다.

8. @Binds

@Module 내부에 사용하여 인터페이스를 구현체에 바인딩할 때 사용한다. 인터페이스와 이를 구현하는 클래스 간의 매핑을 정의할 수 있다.

@Module
@InstallIn(SingletonComponent::class)
interface RepositoryModule {

    @Binds
    fun bindMyRepository(
        impl: DefaultMyRepository // 실제 구현체
    ): MyRepository // 인터페이스

}

위 예시처럼 Repository나 DataSource, 등 인터페이스와 실제 구현체를 연결 해주는 역할을 한다.

9. @Qualifier

동일한 타입의 서로 다른 인스턴스를 구분하기 위해 사용된다. 커스텀 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
) {
	...
}

10. @HiltViewModel

ViewModel 클래스에 붙이며, @Inject 생성자와 함께 사용하여 ViewModel에 의존성을 주입할 수 있다.
이 어노테이션들은 Hilt의 의존성 주입 시스템을 구성하는 중요한 요소들이며, 주입 위치나 범위에 따라 적절하게 사용하여야 한다.

@HiltViewModel
class MainViewModel @Inject constructor(
	private val myRepository: MyRepository
)

0개의 댓글