Android

안드로이드 DI 라이브러리 Koin 에 대해

최데브 2021. 1. 24. 22:38

DI 가 의존성 주입을 의미하는 단어라는것은 알고 있었다.

Spring 공부할때 bean 으로 의존성 주입하고 어노테이션으로 썼던 기억이 난다.

 

안드로이드에서는 사용해보지 않았는데 Dagger2 라는 라이브러리가 그 역할을 해주고 있다는건 알고 있었다.

그렇게 알고만 있다가 새로 공부하고 프로젝트에 적용해보고 싶은 욕심이 생겨서 찾아보던 중

Dagger2와 성능차이도 나지 않는데 훨씬 쓰기 쉽고 직관적인 라이브러리 Koin 이 있다는걸 알고

사용해보기로 했다.

 

쉽고 좋은데 쓰지 않을 이유는 없지.

먼저 DI를 왜 쓸까? 사용하면 얻는 이점부터 알아보자.

 

- 의존관계 설정이 프로그램 실행시에 이루어지기 때문에 컴포넌트간 결합도를 낮춘다.

- 코드 재사용성이 증가한다.

- 단위 테스트의 편의성을 높여준다.

- 스코프를 사용하여 객체를 관리할 수 있다.

 

다음은 Koin 에서 자주 등장하는 단어들을 살펴보자.

 

- module : Koin 모듈을 정의한다. 제공할 객체의 명세가 된다.

- factory : 인스터스를 가져올 factory 패턴을 선언한다. 이 안에 만들어둔 인스턴스는 다른곳에서 사용할때마다 새로운 인스턴스를 가져오도록한다. 쉽게 말하면 한번 여기서 만들어두면 그걸 공장처럼 계속 새로 찍어낸다.

- single : factory 와 반대로 싱글톤과 같은 개념으로 App 전체 주기동안 계속 살아있는 객체를 만들때 사용한다.

- bind : 종속시킬 class 나 interface 를 주입한다.

- get : bean이나 factory를 통해 정의된 컴포넌트를 가져온다. 바로 객체를 주입할때 사용.

- by inject() : 바로 주입하는 get과 다르게 lazy 하게 호출시 사용하는 방법.

 

예제를 코드로 한번 봐보자. 보면 금방 이해가 된다.

var modelKoin = module {
    //factory는 이 안에 들어있는 클래스를 공장처럼 찍어내는 역할을 한다.
    //inject 할때마다 새로운 인스턴스를 가져온다.
    factory<DataModel> {
        DataModelImpl(get())// 이 클래스가 필요한 곳에서 get 을 하면 이 클래스가 거기로 들어간다.
    }
}

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

var DiModules = listOf(modelKoin, viewModelKoin)

1. 먼저 module 을 적어주고 {} 를 열어서 모듈을 정리한다.

2. factory를 사용해서 만들면 여러군데서 사용할때마다 새로운 인스턴스로 만들어진다.

3. viewModel 을 DI로 주입할때는 module 안에 viewModel 이라고 명시하고 만들어준다.

4. DiModules 안에 listOf 로 모듈이름들을 모두 넣어 묶어주면 최상위 Appliaction 클래스에서 다같이 DI 로 사용가능하게 된다.

 

*추가  MainViewModel(get()) 이런식으로 안에 get()을 적어주면 여기안으로 파라미터를 하나 받겠다는 말이 된다.

 

class Application : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin(applicationContext, DiModules)
        //이런식으로 최상위에서 DiModules 을 넣어서 주입해줌.
    }
}

이렇게 Application 클래스에서 staryKoin 으로 사용하면 의존성이 주입된다. 

정말 간단하다.

 

그럼 직접 View에서 사용할땐 어떨까?

override val viewModel: MainViewModel by viewModel() // Koin 으로 의존성 주입

이런식으로 viewModel의 by viewModel()로 경우 주입해서 사용할 수 있고

var koin_get : BB = get()

이런식으로 get() 으로 주입할 수도 있으며 

 val koin_inject : BB by inject()

by inject()로 lazy 하게 가져올수도 있다.

 

또한 생성자에 넣어주는 식으로도 주입할 수 있다.

 

 

아직 완벽하게 알고 있는것은 아니라 앞으로 알게 될때마다 이 글을 수정해나가도록 하겠다.

 

반응형