정상에서 IT를 외치다

[Android, Koin] 코인을 사용한 의존성 주입 기본 예제 본문

안드로이드

[Android, Koin] 코인을 사용한 의존성 주입 기본 예제

Black-Jin 2018. 12. 5. 12:13
반응형


안녕하세요. 블랙진입니다.


이전 DI 기본 개념과 Dagger2 라는 포스팅을 했었습니다. 안드로이드 개발자들이 DI를 사용하기 위해서 Dagger2를 애용합니다. 하지만 진입장벽이 높아 저도 기본 개념만 익히고 거의 사용을 못했는데요 ㅜㅠ.... 그러던 중 DI를 사용할 수 있게 도와주는 또 다른 라이브러리 Koin 을 알게 되었습니다. 기본 개념부터 실재 프로젝트에 어떻게 사용하면 좋을지에 대해 포스팅을 해보겠습니다. 



Koin Github


A pragmatic lightweight dependency injection framework for Kotlin developers.

Written in pure Kotlin, using functional resolution only: no proxy, no code generation, no reflection.

Koin is a DSL, a light container and a pragmatic API

위 설명 그대로 코인은 코틀린 개발자를 위한 가벼운 의존성 주입 프레임워크 입니다. Dagger2 보다 가볍고 진입장벽이 낮습니다. 처음 의존성 주입을 사용할 때에는 코인을 사용해 보는 것도 좋은것 같습니다.


Koin DSL


Koin provides a DSL to help your describe your components with definitions and start the Koin container with those definitions and to instantiate them when needed.

  • module - create a Koin Module

  • factory - provide a factory bean definition

  • single - provide a singleton bean definition (also aliased as bean)

  • get - resolve a component dependency

  • bind - add type to bind for given bean definition


Example

KoinDocs 의 기본예제를 참고했습니다.


0. setting

// Koin for Kotlin apps
implementation 'org.koin:koin-android:1.0.2'

Koin 의 최신 버전은 github 에서 확인해 주세요


1. package


- HelloRepository

interface HelloRepository {
fun giveHello(): String
}


- HelloRepositoryImpl

class HelloRepositoryImpl : HelloRepository {
override fun giveHello() = "Hello Koin"
}


- MySimplePresenter

class MySimplePresenter(private val repo: HelloRepository) {

fun sayHello() = "${repo.giveHello()} from $this"
}

component 패키지 안에 들어있는 3가지 파일입니다.

정리하면 HelloRepositoryImpl 클래스에 있는 "Hello Koin" 데이터를 MySimplePresenter 에서 받아 출력하는 파일입니다.



2. MyModule

val appModule = module {
// 의존성 주입을 위한 컴포넌트를 생성합니다.

// 싱글톤 인스턴스 제공

single<HelloRepository> { HelloRepositoryImpl() }

// 인스턴스 제공 (매번 생성)
// 의존성 주입이 일어날때마다 객체를 생성하며, 보관 하지 않습니다.
// get() 함수를 호출하면 타입추론을 통해 컴포넌트 내에서 이미 생성된 객체를 참조하게 됩니다.
factory { MySimplePresenter(get()) }
}

MyModule은 코틀린의 패키지 단위 함수로 자바 클래스의 정적 메서드나 필드로 선언한 것과 동일합니다. 여기서는 의존성 주입을 위한 컴포넌트들을 정의합니다. 주석에 적은 것과 같이 HelloRepositoryImpl 객체가 get() 함수를 통해 MySimplePresenter로 참조됩니다. 이때 Single에 <HelloRepository>를 적어준건 Presneter에서 HelloRepository를 파라미터로 받기 때문에 데이터 타입을 명시적으로 적어주었습니다. 만약 Presneter에서 HelloRepositoryImpl을 파라미터로 받게 된다면 Singe { HelloRepositoryImpl() } 이렇게만 적어주어도 동작합니다.



3. MyApplication

import org.koin.android.ext.android.startKoin

class MyApplication : Application() {

override fun onCreate() {
super.onCreate()

// Start Koin
startKoin(this, listOf(appModule))
}
}

startKoin 함수를 통해 appModule 에 있던 컴포넌트들을 의존성 주입을 통해 사용할 수 있게 됩니다.



4. MainActivity

class MainActivity : AppCompatActivity() {

private val firstPresenter : MySimplePresenter by inject()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

textView.text = firstPresenter.sayHello()
}
}

의존성 주입은 inject() 를 통해 간편하게 사용할 수 있습니다. 이렇게 mainActivity 의 textView 에 sayHello() 의 데이터를 객채 생성 없이 사용할 수 있게 됩니다.


Dagger2 보다는 확실히 진입장벽이 낮습니다. DI의 기본 개념을 익히고 사용하기에는 좋은것 같습니다.



<심화자료>


한옥 사는 개발자


TODO APP with koin


Writing DSLs in Kotlin

반응형
Comments