본문 바로가기
개발/안드로이드

Android Kotlin MVVM패턴으로 간단한 검색 앱 만들기 - 2. Koin을 통한 의존성 주입

by darksilber 2019. 5. 31.
반응형

출처: https://deque.tistory.com/109?category=984011 [코딩하는 사람]

 

의존성 주입.. Dependency injection ... 줄여서... DI....

 

 

이걸 왜하느냐!

 

라고 물으시면..

 

 

아주 간단하게,

 

테스팅을 위해서!

라고 답할 수 있지 않을까요..?

 

 

 

 

지금과 같은 MVVM패턴에서

 

뷰모델을 테스팅한다고 칩시다.

 

그럼 뷰모델을 테스팅하려면 뷰모델이 의존하고 있는 모델은.. 어떻게 만들어서 뷰모델에게 줘야 뷰모델을 테스팅 할 수 있을까요?

 

 

간단한 방법으로는 모델을 내부에서 생성하지 않고 생성자의 인자로 주는 것입니다.

 

ViewModel{

val model = Model()

}

 

과 같이 하지 않고

 

ViewModel(val model){

}

 

이렇게

 

 

그러면 뷰모델을 테스팅모듈에서 생성할 때 테스팅용 모델을 뷰모델의 생성자로 '주입' 해줌으로서 뷰모델을 테스팅하기 쉽게 할 수 있는 것이죠.

 

 

 

근데 이걸 일일이 한다?

 

 

꽤.. 불편하고 버그도 많게 될거 같군요..

 

그래서 이러한 의존성 주입 작업을 편하게 해주는 몇가지 라이브러리가 있습니다.

 

그중 가장 대표적인것이 Dagger2 !

 

근데... 대거는.. 너무 어렵습니다!

 

솔직히 저같은 초보는..

 

의존성이 적은 MVVM패턴 같은 데서는

 

대거 배워서 적용한다음 대거를 위해 프로젝트 구조를 싹 다 바꾸는 것보다..

 

그냥 라이브러리 없이 의존성 주입하는게 더 편합니다...ㅜㅜㅜ

 

 

 

근데, Koin은 너무 편합니다!

 

학습할 것도 많이 없고, 바꿀것도 많이 없고, 코틀린에 특화되어있고, 뷰모델에 또한 특화되어있기도 하지요.

 

관련되서는 이 링크를 한번 보시면 좋을듯 합니다.

https://medium.com/harrythegreat/kotlin%EC%97%90%EC%84%9C-dagger2-%EC%93%B0%EA%B8%B0-%ED%9E%98%EB%93%9C%EB%8B%88-%EA%B7%B8%EB%9F%BC-%EB%84%8C-koin%EC%9D%B4%EC%95%BC-e9e42ec1288e

 

 

 

그래서, 저는 코인을 쓰고, 이번 글에서는 코인에 관해 간단하게 설명해보겠습니다.

 

 

 

 

 

 

일단 코인 공식 홈페이지입니다.

 

https://insert-koin.io/

 

 

이건 깃헙 리포지토리 입니다.

 

https://github.com/InsertKoinIO/koin

 

 

 

사용방법을 말씀드리며 설명을 해보겠습니다.

 

 

일단 디펜던시에 추가해줍시다

 

// koin
implementation "org.koin:koin-androidx-scope:1.0.2"
implementation "org.koin:koin-androidx-viewmodel:1.0.2"

AndroidX용 입니다. AndroidX를 안쓰시면 깃헙 레포지토리 리드미등을 참고해서 다른걸로 바꿔주세요

 

 

 

먼저 의존성 주입에 사용할 모듈을 짜봅시다.

 

이 모듈이 뭐냐면, 간단하게 말해서 의존성 주입을 하는 실제 코드, 혹은 의존성 주입을 위한 설계도, 정도로 이해해주시면 됩니다.

 

var modelPart = module {
factory {
DataModelImpl()
}
}

var viewModelPart = module {
viewModel {
MainViewModel(get())
}
}

var myDiModule = listOf(modelPart, viewModelPart)


끝입니다.

 

간단하죠!

 

대거로 짰으면 벌써 클래스 6개는 나왔습니다...

 

 

 

일단 factory{}와 viewModel{}이 보이네요

 

팩토리는 말그대로 공장입니다. DataModelImpl()이라는 클래스를 뚝딱뚝딱 만들어 주죠

 

그러면 이제 다른 클래스에서 해당 부분이 필요하다면 단순히 get()을 해주면 팩토리로 만든 클래스가 쏘옥~하고 들어갑니다.

 

팩토리외에도 single{}이 있는데, 이건 싱글톤패턴처럼 어플리케이션에서 단 하나만 만듭니다. 저는 보통 Retrofit을 통해 만든 서비스 클래스를 single로 만듭니다.

 

이렇게 얻은 객채들은 방금 말한것처럼 get()으로 넣는것 이외에도 by inject()를 통해서도 얻을 수 있습니다.

 

 

그리고 viewModel{}은 말 그대로 뷰모델을 만듭니다.

 

액티비티에서 by viewModel()을 통해서 얻어올 수 있죠.

 

 

 

두번째로 Application 클래스를 상속 한뒤 onCreate에 딱 한줄만 넣습니다.

 

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin(applicationContext, myDiModule)
}
}

startKoin(context, module)

 

이러면 이제 의존성이 주입됩니다.

 

 

(Application 클래스를 상속한 뒤 메니페스트에서

android:name=".MyApplication"

와 같이 설정해 주는걸 잊지 마세요!)

 

 

주입할 때는 이런식으로 코드 내에서나,

 

val service : BusinessService by inject()

 

 

이렇게 생성자나,

 

class Controller(val service : BusinessService){ fun hello() { // service is ready to use service.sayHello() } }

 

 

이렇게 뷰모델을 주입할 수 있습니다.

 

val vm : MyViewModel by viewModel()

 

 

 

 

추가로 테스팅을 할 때에는

 

 

// Just tag your class with KoinTest to unlick your testing power class SimpleTest : KoinTest { // lazy inject BusinessService into property val service : BusinessService by inject() @Test fun myTest() { // You can start your Koin configuration startKoin(myModules) // or directly get any instance val service : BusinessService = get() // Don't forget to close it at the end stopKoin() } }

 

 

 

이렇게 해주면 됩니다.

 

 

 

 

 

실제로 이전 게시물의 메인 액티비티에서는

override val viewModel: MainViewModel by viewModel()

와 같이 뷰 모델을 주입해주게 구현했습니다.

 

 

 

 

 

 

 

다음 게시물에서는 RxJava와 Retrofit을 통해 카카오 Api로 검색하는 것을 설명해보겠습니다.



반응형

댓글