[MVVM 정복] 5. View에 Koin으로 의존성 주입하기
728x90
반응형

이번편에서도 코드를 보면서 학습하길 권한다.

 

conquerex/mvvm-template

MVVM 학습과 앞으로 활용을 위한 템플릿. Contribute to conquerex/mvvm-template development by creating an account on GitHub.

github.com

 

 

 

우선 MainActivity를 준비하자. 물론 activity_main.xml도 같이 세팅하자. 여기서 DataBinding이 나온다. 하지만 생각보다 단순한 개념이기에 참고 링크만 남겨둔다. MVVM에 데이터바인딩이 필수라고 하는 분이 있고 그렇지 않다고 얘기하는 분도 있었다. 필수라고 하는 분은 의존성이 낮아짐을 근거로 삼고, 필수가 아니라는 분은 디자인패턴적으로 봤을 때 없어도 되기 때문이라고 한다. 판단은 여러분이... (떠넘기기. 우헤헤)

 

import org.koin.androidx.viewmodel.ext.android.viewModel
import what.the.mvvm.viewmodel.MainViewModel

override val viewModel: MainViewModel by viewModel()

위 코드는 MainActivity의 일부이다. 의존성 주입이 어떻게 이루어졌는지 살펴보기 위해서 가지고 왔다.

  • by inject() : 위 코드에 나타나있지 않지만 많이 쓰인다. lazy하게 호출하여 생성
  • get() : 바로 주입하는 방식
  • by viewModel() : inject의 ViewModel 버전. 역시 lazy하게 생성됨

위에서 layoutlayoutResourceId는 BaseAcitvity의 아래 코드에 적용을 해야 레이아웃에 바인딩 되기 때문에 get을 사용한 것이다.

viewDataBinding = DataBindingUtil.setContentView(this, layoutResourceId)

 

여기서 착각하지 말아야 할 것!!!!

바로 위의 get()과 Module에서 사용한 get()은 다르다.

  • View의 get()
    • ComponentCallbacks 내부의 메소드. 의존성을 실제로 주입하는 역할
  • MyModule의 get()
    • 컴포넌트내에서 알맞은 의존성을 주입함. 타입 추론을 통해 컴포넌트 내에서 이미 생성된 객체를 참조
    • ModuleDefinition 내부의 메소드
  • Custom getter의 get()
    • 연산을 수행한 수 결과를 반환해야 하는 것과 같이 단순하지 않은 값을 커스텀 접근자에 줄 수 있다.
    • backing field를 사용하지 않는다. (요게 뭔지는 따로 학습을 해주세요. 떠넘기기. 데헷)
    • 생긴건 아래를 참고해주세요.
override val layoutResourceId: Int
    get() = R.layout.activity_main // get() : 커스텀 접근자, 코틀린 문법

 

가장 위의 코드에서 viewModel이 "by viewModel()"로 의존성 주입이 된다. 그런데 DI는 어떻게 주입 대상인지 알고 자동으로 해주는걸까? 주입하는 방식을 두가지 정도 다뤄본다.

 

첫번째, 직접 코드로 입력할 수 있다. 가장 위 코드의 ViewModel이 그런 방식.

// 첫번째, 직접 주입
override val viewModel: MainViewModel by viewModel()
val phone : PersonInfo by inject() // 예시

두번째, 생성자에 주입하는 방식이 있다.

// 두번째, 생성자에 주입
class MainViewModel(private val model: DataModel) : BaseViewModel() {...}
class DataModelImpl(private val service: KakaoSearchService) : DataModel {...}

// DI 모듈
var modelPart = module {
    factory<DataModel> {
        DataModelImpl(get())
    }
}

var retrofitPart = module {
    single<KakaoSearchService> {...}
}

factory와 single의 제너릭 내부에 주입할 대상을 지정하면 전역적으로 확인해서 의존성을 주입한다. (캬. 대박이네)

 

참고자료
- https://medium.com/@jsuch2362/android-%EC%97%90%EC%84%9C-mvvm-%EC%9C%BC%EB%A1%9C-%EA%B8%B4-%EC%97%AC%EC%A0%95%EC%9D%84-82494151f312
- https://woovictory.github.io/2019/05/08/Android-koin/

 

728x90
반응형