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
koin io - https://beta.insert-koin.io/