[Android] Hilt Assisted, AssistedInject 란?

오규성·약 18시간 전
0

HiltCompile 시점에서 의존성 주입 패턴 코드를 자동으로 생성해주기에 보일러플레이트 코드가 감소하고 모듈, 코드 간 커플링(결합도) 를 낮춰 준다.

하지만 객체를 생성할 대때, 우리는 컴파일 시점이 아닌 런타임 시점에 특정 데이터를 전달해줘야 하는 경우가 있다.

예를 들어, 서버로부터 내려온 유저 데이터 같은 경우는 실시간마다 값이 바뀔 수 있기에 컴파일 시점에서 알 수 없다.

그렇기에 Dagger Hilt 에는 의존성 주입과 함께 런타임 시점 데이터를 주입을 위해 AssistedAssistedInject 라는 Annotation 을 제공한다.


# 과거 방식

이 부분은 읽지 않아도 되지만, 과거 Hilt 를 사용하며 AssistedInject 를 사용하기 위해 얼마나 귀찮은 과정을 거쳤는지 간단하게 알아보려고 한다.

과거에는 개발자가 직접 Factory 코드를 생성해줘야했다.

class MainViewModel @AssistedInject constructor(
    @Assisted val userId: Int,
    private val getUserUseCase: GetUserUseCase
) : ViewModel() {
    @AssistedFactory
    interface MainViewModelFactory {
        fun create(userId: Int): MainViewModel
    }

    private val _count = MutableStateFlow(0)
    val count = _count.asStateFlow()

    fun increase(){ _count.getAndUpdate { it + 1 } }

    companion object {
        fun provideFactory(
            assistedFactory: MainViewModelFactory,
            userId: Int
        ): ViewModelProvider.Factory = object : ViewModelProvider.Factory {
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                return assistedFactory.create(userId) as T
            }
        }
    }
}

예를 들어 위와 같이 Runtime 에 공급받을 userId 라는 파라미터가 존재하는 경우, 이것 하나를 위해 Factory 를 생성하는 코드를 구현하고, 이것을 viewModel 객체를 생성할 때 직접 사용해야했다.

이와 같은 방식은 보일러플레이트 코드가 생성되며, 추후 관리의 어려움으로 이어졌다.

# 현재방식

위와 같이 불편했던 방식은 Hilt 2.49 부터 매우 간편하게 변경되었다.
이전에는 AssistedInject 를 사용하기 위해서는 hiltViewModel 을 사용하면 안되었지만, 이제는 이를 사용해도 되고, 구현 방법에는 애초에 이를 사용해야한다.

@HiltViewModel(assistedFactory = MainViewModel.MainViewModelFactory::class)
class MainViewModel @AssistedInject constructor(
    @Assisted val userId: Int,
    private val getUserUseCase: GetUserUseCase
) : ViewModel() {
    @AssistedFactory
    interface MainViewModelFactory {
        fun create(userId: Int): MainViewModel
    }

    private val _count = MutableStateFlow(0)
    val count = _count.asStateFlow()

    fun increase(){ _count.getAndUpdate { it + 1 } }
}

한 눈에 보더라도 코드의 양이 엄청나게 줄고, HiltViewModel 이 사용하는 assistedFactory 가 무엇인지 한 눈에 확인할 수 있게 되었다.

현재 이를 구현하는 방법은 다음과 같다.

val viewModel = hiltViewModel { factory: MainViewModel.MainViewModelFactory ->
    factory.create(2)
}

참고

profile
안드로이드 개발자 Gyu 의 개발 블로그 !

0개의 댓글