안드로이드

[Android] Di(Dependency Injection) Koin에 대해 알아보자

코딩하는후운 2022. 11. 4. 16:08
반응형

Di(Dependency Injection) Koin에 대해 알아보자

DI(Dependency Injection)이란?

Dependency는 의존성이고 Injection은 주입이란 의미라 단순 번역은 의존성 주입입니다.
의존성이란 A라는 클래스가 내부에서 B라는 클래스를 참조하는 경우 A클래스->B클래스 의존성을 갖는다고 할수 있다.

Ioc(Inversion of Control)

제어역전이란 말로 해석이 되며, 제어역전은 개발자가 직접 프로그램의 흐름을 제어하는 코드를 작성하지 않고
외부 프레임워크의 흐름 제어를 받도록 하는 개발 원칙으로 Ioc를 따라 소프트웨어를 개발하면 인스턴스의 생성이나
이벤트 처리등의 호출을 프레임워크가 알아서 해주게 됩니다.

간단히 말하면 모든 제어 권한을 자신이 아닌 다른 대상에게 위임하는 것입니다.

Koin이란?

Koin은 코틀린을 위한 DI라이브러리로 학습곡선이 높은 Dagger에 비해 상대적으로 낮은 학습곡선을 가지고 있으며 순수 코틀린만으로 작성되었으며 어노테이션 프로세싱 및 리플렉션을 사용하지 않기 때문에 상대적으로 더 가볍다.

Koin 구현

1. 모듈 생성하기(Koin DSL)
2. Android Application Class에서 startKoin()으로 실행하기
3. 의존성 주입

우선 Koin DSL을 이용하여 모듈을 설치하여야 하는데 DSL은 무엇일까?
DSL(Domain specific Language)으로 번역을 하자면 도메인 특화 언어로 위키피디아에는
"특정한 도메인을 적용하는데 특화된 언어"라고 정의

Koin DSL은 아래와 같이 있습니다.
-applicationContext: Koin 모듈 생성
-factory: 매번 inject 할때마다 인스턴스 생성
-single: 싱글톤 생성
-bind: 종속시킬 class나 interface를 주입
-get: 컴포넌트내에서 알맞은 의존성을 주입함


모듈은 아래와 같이 만들 수 있습니다.
import org.koin.dsl.module

[MyModule.kt]
//여기서 Koin DSL을 이용하여 모듈을 만들어줍니다.

val appModule = module{
  single<Repository> { RepositoryImpl() } //싱글톤으로 생성
  factory{ MyPresenter(get()) } //의존성 주입때마다 인스턴스 생성, get()을 이용하면 위에서 선언된 적절한 클래스가 주입됩니다.
}



[Repository.class]
모듈에서 사용하는 인터페이스입니다.

interface Repository{
  fun getMyData(): String
}



[RepositoryImpl.class]
인터페이스 구현 클래스

class RepositoryImple : Repository{
  override fun getMyData(): String{
    return "Hello Koin"
  }
}



[MyPresenter.class]
Repository를 사용하는 Presenter입니다.
생성자에서 repository의 인스턴스가 의존성 주입이 되는데, 모듈에서의 get()을 통해서 자동으로 주입됩니다.

class MyPresenter(private val repository: Respository){
  fun sayHello() = "${repository.getMyData()} from $this"
}



[MyApplication.class]
Application Class 에서 startKoin()

class MyApplication: Applicaton(){
  override fun onCreate(){
    super.onCreate()
    startKoin{
      androidContext(this@MyApplication)
      module(appModule)
    }
  }
}




[MyActivity.class]

private val myPresenter: MyPresenter by inject()  //이 부분을 통해서 의존성 주입이 일어납니다.

 


Koin 실제 적용

 

-그래들

// Koin AndroidX Scope features
implementation "org.koin:koin-androidx-scope:$koin_version"
// Koin AndroidX ViewModel features
implementation "org.koin:koin-androidx-viewmodel:$koin_version"
// Koin AndroidX Fragment features
implementation "org.koin:koin-androidx-fragment:$koin_version"
//Koin extended & experimental features
implementation "org.koin:koin-core-ext:$koin_version"





-Application

startKoin {
    androidLogger(Level.DEBUG)
    androidContext(this@AppApplication)
    fragmentFactory()
    modules(
        listOf(
            networkModule,
            fragmentModule,
            viewModelModule,
            repositoryModule,
            apiManagerModule,
            dataSourceModule
        )
    )
}



-Activity

private val mainFragment by inject<MainFragment> {
    parametersOf(null)
}

onCreate(){
  setupKoinFragmentFactory()
}



-Fragment

private val mainVM: MainViewModel by viewModel()



-Module

val fragmentModule = module {
    fragment { MainFragment() }
}

val viewModelModule = module {
    viewModel { MainViewModel(get()) }
}

val apiManagerModule: Module = module{
    single{
        ServiceManager((get() as Retrofit).create(GithubService::class.java))
    }
}

 

반응형

'안드로이드' 카테고리의 다른 글

[Android] DB Realm Migration  (0) 2022.11.04
[Android] Lottie 애니메이션  (0) 2022.11.04
Android KeyStore  (0) 2022.11.04
[Android] Gradle KeyStore 셋팅  (0) 2022.11.04
[Android] Fragment 객체 생성 이유  (0) 2022.11.04