Hyeyeon blog

[Android] Koin - Dependency Injection Library 본문

개발/Android

[Android] Koin - Dependency Injection Library

Hyeyeon.P 2019. 1. 27. 04:16
반응형

 

1. 정의

A pragmatic lightweight dependency injection framework for Kotlin developers

(Dependency Injection 보다 Service Location에 가까움)

2. 대상

코드 생성의 부하 때문에 작거나 중간 사이즈의 앱에 적합

3. Dagger vs Koin

Dagger는 컴파일 과정에서 DI를 주입하기 때문에 컴파일 오버헤드가 있는 반면, Koin은 런타임 시 DI를 주입하기 때문에 상대적으로 런타임 오버헤드가 있음

4. 기본 사용법

   (1) gradle.xml

1. build.gradle(Project)
buildscript {	
	ext.koin_version = '2.2.2'
}

2. build.gradle(Module)
dependencies{
  // 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"
}

    - 2022년 2월 1일부터 jcenter 서비스가 중단되어 maven로 사용해야합니다 . (참고 : insert-koin.io/docs/setup/v3)

1. build.gradle(Project)
buildscript {	
	ext.koin_version = '3.0.1-beta-1'
}

2. build.gradle(Module)
dependencies{
	implementation "io.insert-koin:koin-core:$koin_version"
}

   (2) AppModule.kt

- module: Koin 모듈 정의 (module에 만들고자 하는 생성자를 적어줘야 함)

- single: 앱이 살아있는 동안 전역적으로 사용 가능한 객체를 생성

- viewModel: Activity나 Fragment에 각 viewModel을 주입

- factory: inject 시점에 해당 객체를 매번 생성 

- get: 정의된 컴포넌트를 가져옴

val appModule = module {
    viewModel { MyViewModel(get()) }
    single { ResourceProvider() }
    single { MyFragment() }

    // 외부에서 받아오는 파라미터가 있는 경우
    //  viewModel { (handler: MyEventHandler) -> MyViewModel(handler, get()) }
}
class MyViewModel(val resourceProvider : ResourceProvider) { .. }

   (3) Koin 초기화

open class App : Application(){
    override fun onCreate() {
        super.onCreate()

        startKoin(this, appModule)

       // 모듈을 여러개 등록할 경우
       // startKoin(this, listOf(appModule, networkModule))
    }
}
// AndroidManifest 에 등록
<application
        android:name=".App"
        .. >

(4) 주입

      - single, factory:    by inject()로 주입

      - viewModel:    by viewModel()로 주입

class MyActivity : AppCompatActivity(){
	import org.koin.android.viewmodel.ext.android.viewModel

    private val viewModel : MyViewModel by viewModel()
    private val fragment : MyFragment by inject()
   
   // 파라미터 있는 경우
   // private val viewModel : MyViewModel by viewModel { parametersOf(handler) }
   ... 
}

 

5. Scope

   (1) Definition

        - single: 전체 컨테이너에 영속적인 객체를 생성

        - factory: 매번 새로운 객체를 생성하므로 컨테이너에서 영속성을 갖지 않는 객체를 생성

        - scope: 명시된 scope lifetime에 영속성을 갖는 객체를 생성

   (2) Create & Retrieve Scope

        - createScope(id: String): Koin scope registry에서 해당 id의 scope를 생성

        - getScope(id: String): Koin scope registry에서 이전에 생성된 해당 id의 scope을 반환

        - getOrCreateScope(id: String): Koin scope registry에서 해당 id의 scope가 이미 생성되어있으면 반환, 아니면 생성함

   (3) Scope 생성 

       위의 메서드를 사용하기 위해 KoinComponent에서 getKoin()을 사용

module {
    scope("scope_id") { Presenter() }
}

// create a scope
val session = getKoin().createScope("scope_id")

// or get scope if already created before
val session = getKoin().getScope("scope_id")

// will return the same instance of Presenter until Scope 'scope_id' is closed
val presenter = get()

(4) Scope 주입 

class Presenter(val userSession : UserSession)
module {
    // Shared user session data
    scope { UserSession() }
    // Inject UserSession instance from "session" Scope
    factory { Presenter(get())}
}

(5) Scope 종료 

      Scope.close() 호출  

// from a KoinComponent
val session = getKoin().createScope("session")
// will return the same instance of Presenter until 'session' is closed
val presenter = get()

// close it
session.close()
// instance of presenter has been dropped

 

[참고]

[Medium - Koin developers]

[Dagger2 vs Koin]

[Moving from Dagger to Koin]

[Koin과 함께하는 안드로이드 의존성 주입]

 

[출처]

[Github]

[Koin Reference Documentation]

728x90
Comments