Android/DI

Koin - DI 라이브러리 koin을 알아보자

봄석 2019. 5. 1. 22:15

Koin - DI 라이브러리 koin을 알아보자 

Koin에 대하여 알아보기 전에 먼저 DI란게 어떤것인지 가볍게 알아보도록 하겠습니다 .


- DI(Dependency Injection,의존성 주입) 이란 ? 

현재 객체가 다른 객체와 상호작용(참조)하고 있다면 현재 객체는 다른 객체에 의존성을 가집니다.

public class PetOwner{
    private AnimalType animal;

    public PetOwner() {
        this.animal = new Dog();
    }
}

간단한 예로 PetOwner객체는 Dog에 의존적인 상황입니다.

이러한 의존성이 위험한 이유는 

  •  PetOwner객체는 AminalType객체 생성을 제어하기 대문에 두객체간  긴밀한 밀접이 생기고, AnimalType객체를 변경하면 PetOwner객체로 변경됩니다.
  • 즉, 하나의 모듈이 바뀌면 의존한 다른 모듈까지 변경되어야 합니다
  • 또한 두 객체아시의 의존성이 존재한다면 Unit Test 작성이 어려워지게 됩니다

DI는 

  • 구성요소간의 의존 관계가 소스코드 내부가 아닌 외부 설정 파일등을 통해 정의되게하는 디자인 패턴중 하나입니다
  • 예를들면, 카페에서 커피를 만드는데 커피 머신이 어떤 부품으로 구성되어있는지 바리스타는 알필요가 없다는 개념과 비슷합니다.
  • 이렇게 분리시켜 놓으면 객체의 생성과 사용을 분리시킬 수 있고, 재사용이 유연해집니다.

- koin setup

project 수준의 gradle에 아래 내용을 추가합니다 .

koin_version = '2.0.0-rc-2'

 repositories {
        jcenter()
    }

그리고 앱수준의 gradle에 아래와 같은 dependency를 추가합니다 

implementation "org.koin:koin-android:$koin_version"


/** 아래는 옵션으로 필요한 부분이 있으면 추가해줍니다 **/

- Core features
    // Koin for Kotlin
    implementation "org.koin:koin-core:$koin_version"
    // Koin extended & experimental features
    implementation "org.koin:koin-core-ext:$koin_version"
    // Koin for Unit tests
    testImplementation "org.koin:koin-test:$koin_version"
    // Koin for Android
    implementation "org.koin:koin-android:$koin_version"

- Android 
    // Koin for Android
    implementation "org.koin:koin-android:$koin_version"
    // Koin Android Scope feature
    implementation "org.koin:koin-android-scope:$koin_version"
    // Koin Android ViewModel feature
    implementation "org.koin:koin-android-viewmodel:$koin_version"
    
- Android X
    // AndroidX (based on koin-android)
    // Koin AndroidX Scope feature
    implementation "org.koin:koin-androidx-scope:$koin_version"
    // Koin AndroidX ViewModel feature
    implementation "org.koin:koin-androidx-viewmodel:$koin_version"
    
    
- Ktor
    // Koin for Ktor Kotlin
    implementation "org.koin:koin-ktor:$koin_version"


- DSL 키워드 

 

  • module - Koin모듈을 정의할때 사용
  • factory - inject하는 시점에 해당 객체를 생성
  • single - 앱이 살아있는 동안 전역적으로 사용가능한 객체를 생성
  • bind - 생성할 객체를 다른 타입으로 바인딩하고 싶을때 사용
  • get - 주입할 각 컴포넌트끼리의 의존성을 해결하기 위해 사용

- 예제로 알아보기 

1)모듈 생성

// Given some classes 
class Controller(val service : BusinessService) 
class BusinessService() 

// just declare it 
val myModule = module { 
  single { Controller(get()) } 
  single { BusinessService() } 
} 

2)app 레벨에서 Koin start 

class MyApplication : Application() {
  override fun onCreate(){
    super.onCreate()

    startKoin {
      androiContext(this@MyApplication)
      modules(myModule)
    }
  } 
} 

3-1 ) 의존성 주입

 class MyActivity() : AppCompatActivity() {

    val service : BusinessService by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
       
        val service : BusinessService = get()
    }
}

3-2) 생성자에 의해 의존성 주입하기 

class Controller(val service : BusinessService){ 
  
  fun hello() {
     service.sayHello()
  }
} 

4) 단위 테스트 하기

class SimpleTest : KoinTest { 
  
  val service : BusinessService by inject()

  @Test
  fun myTest() {
  
      startKoin { modules(myModules) }
      
      val service : BusinessService = get()
  }
} 

 


 

 

github - https://github.com/InsertKoinIO/koin

 

InsertKoinIO/koin

KOIN - a pragmatic lightweight dependency injection framework for Kotlin - InsertKoinIO/koin

github.com

koin io - https://beta.insert-koin.io/

 

insert-koin.io

a smart Kotlin dependency injection framework

insert-koin.io