Koin 잘 사용하기

hongbeom
hongbeomi dev
Published in
6 min readJun 3, 2020
Photo by Icons8 Team on Unsplash

what is Koin?

Koin은 Android에서 주로 사용되는 경량화된 의존성 주입용 프레임워크입니다. 여기서 말하는 의존성 주입은 디자인 패턴 중의 하나인데 객체를 생성하고 사용하는 관심사를 분리하는 것에 목적을 가지고 있습니다.

의존성 주입의 장점은 다음과 같습니다.

  • 의존 관계 설정이 실행시에 이루어지므로 컴포넌트 간의 결합도를 낮춘다.
  • 코드 재사용성이 증가한다.
  • 단위 테스트의 편의성을 높여 준다.
  • 스코프를 사용하여 객체를 관리할 수 있다.

또 다른 유명한 Android용 의존성 주입 프레임워크에는 Dagger가 있는데 러닝커브가 상대적으로 높으므로 우선 Koin부터 차근차근 알아보도록 하겠습니다.

Set Up

Koin을 사용하기 위해서는 먼저 root 수준의 build.gradle 파일에 우선 버전을 작성해주고

koin_version= "2.1.5" // 2020.06.03 최신 버전

jcenter를 리포지토리 부분에 추가시켜줍니다.

repositories {
jcenter()
}

그리고 app 수준의 build.gradle 파일에 dependency를 설정해줍니다.

buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.koin:koin-gradle-plugin:$koin_version"
}
}

apply plugin: 'koin'

마지막으로 다음과 같은 dependency를 필요에 따라 설정해주면 됩니다.

// 코어
implementation "org.koin:koin-core:$koin_version"
// 유닛 테스트
testImplementation "org.koin:koin-test:$koin_version"
// AndroidX Scope 생성 - 삭제 자동화
implementation "org.koin:koin-androidx-scope:$koin_version"
// AndroidX ViewModel
implementation "org.koin:koin-androidx-viewmodel:$koin_version"
// AndroidX Fragment
implementation "org.koin:koin-androidx-fragment:$koin_version"

StartKoin

Koin은 DSL을 사용하여 프로젝트 의존성을 관리합니다. 단순하게 main() 에서 이런식으로 시작할 수 있습니다.

물론 안드로이드에서도 쉽게 사용할 수 있습니다.

Modules & Definitions

이제 위에서 살펴본 modules()안에서 의존성을 관리하는 모듈에 대해 알아봅시다.우리가 요런 리포지토리 클래스를 사용한다고 가정해보겠습니다.

그리고 이렇게 간단하게 모듈을 만들 수 있습니다.

현재 module 안에 singleMyRepository()를 넣어주었는데 이것은 Repository를 singleton으로 주입하되 그것의 구현체로 MyRepository()를 주입해주는 것을 의미합니다.

다음으로 넘어가기 전에 우선 방금 만든 module 같은 DSL들이 어떤게 있는지 먼저 살펴보겠습니다.

  • module { } - 코인 모듈 또는 하위 모듈 생성 (모듈 내부)
  • factory { } - 항상 새로운 인스턴스를 생성하도록 해줌.
  • single { } - 싱글톤 타입으로 지정해줌.
  • get() - 컴포넌트 종속성을 해결해줌 (필요한 컴포넌트를 주입받음)
  • named() - Enum이나 String으로 한정자를 정의해줌.
  • bind - 지정된 컴포넌트의 타입을 추가적으로 바인딩해줌.
  • getProperty() - 필요한 프로퍼티를 가져옴.

각각 예시를 보며 살펴보겠습니다.

우선 요런 클래스 및 인터페이스를 사용한다고 가정해 봅시다.

그리고 이렇게 사용할 수 있습니다.

이번엔 한정자를 사용해보겠습니다. 이 한정자는 문자열이나 타입일 수 있으며 named() 를 사용합니다. 또한 한정자를 사용하게 되면 해당하는 한정자의 이름이나 타입으로 생성된 scope에서만 블록 내의 객체를 사용할 수 있습니다.

다음으로 bind 를 사용해보겠습니다.

이런식으로 모듈을 만들어 준 후 다른 모듈과 합쳐서 사용할 수 있습니다.

정의한 모듈을 다른 모듈에서 재정의하여 사용할 수도 있습니다.

즉각적으로 모듈의 인스턴스를 선언할 수 있는 기능도 존재하며 한정자 또는 보조 타입을 사용하여 정의를 만들 수도 있습니다.

For Android

이제 Android에서 사용하는 법을 알아보겠습니다. 위에서 알아본 방법으로 모듈을 생성한 후 사용하면 되는데, Context를 파라미터로 받아서 사용해야하는 경우가 있습니다. 그럴땐 이런 식으로 Context를 주입해 줄 수 있습니다.

이렇게 모듈에 선언한 컴포넌트들은 Activity나 Fragment에서 매우 간단하게 사용할 수 있습니다.

ViewModel 또한 쉽게 주입 받을 수 있습니다.

먼저 모듈을 만들어줍니다.
끝.

상당히 쉽고 간편하게 DI를 사용할 수 있는 것이 큰 장점으로 꼽히는 Koin이지만 성능적으론 Dagger에 못 미친다는 평이 많았는데 2.0 버전에서 inject 성능이 비슷해질 정도로 많이 향상되었다는 생각이 들었습니다.

성능 측정 및 Koin 2.0 소개 링크

Koin 1.0 당시 벤치마킹 성능..처참..🤨
Koin 2.0 — 편안..😌 (2.1 버전은 더 빨라졌습니다.)

이번에 2.1버전이 새로 출시됨에 따라 scope 등 리뉴얼되거나 새로 생긴 DSL에 대해서는 이어지는 글에서 정리하여 올려보도록 하겠습니다.

읽어주셔서 감사합니다 🙌

--

--