Android

koin 에서 viewmodel 을 대상 클래스를 generics 로 전달 받기 ?

aucd29 2019. 5. 22. 17:30
대충 잘 쓰고 있는 dagger2 의 난이도가 너무 높은지 안드로이드 개발 시장이 koin 으로 넘어가고 있는 듯 싶은데
그래서 마이그 할까 싶어서 dagger2 에서 쓰던 코드를 koin 으로 바꾸려는 시작 부터 난 to the 감...

abstract class BaseDaggerRuleActivity<T: ViewDataBinding, M: ViewModel>
    : BaseActivity<T>() {

    @Inject lateinit var mDisposable: CompositeDisposable
    @Inject lateinit var mViewModelFactory: DaggerViewModelFactory


대충 koin 문법으로는 아래와 같이 하면 될까 했는데 안된다.. =_ =

abstract class BaseKoinActivity<T: ViewDataBinding, out M: ViewModel>
    : BaseActivity<T>() {
    protected val mDisposable by inject<CompositeDisposable>()
    protected val mViewModel by viewModel<M>()

viewModel<T>() 이 inline 인 데다가 T 의 경우 reified 이 므로 generics 가 안먹는 상황.. =_ =
좀 더 뒤적거려야 할 시점.. =_ =;

쉬운게 없군

덧.. https://github.com/InsertKoinIO/koin/issues/56 에 글을 보고 인자로 클래스 를 받는게 있는데 그건 좀 아닌것 같고 =_ =

그나마 이게 제일 현실적인 대안 같은 =_ =
open class BaseFragment<M : ViewModel> : Fragment() {
    val viewModel: M by lazy { getViewModel(viewModelClass()) }

    @Suppress("UNCHECKED_CAST")
    private fun viewModelClass(): KClass<M> {
        // dirty hack to get generic type https://stackoverflow.com/a/1901275/719212
        return ((javaClass.genericSuperclass as ParameterizedType)
            .actualTypeArguments[0] as Class<M>).kotlin
    }
}

마침 내겐 Refect fun 을 또 만들어놨고 ㅎ
inline fun classType(obj: Any, index: Int) =
        (obj.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[index]