Koin - DI

HEETAE HEO·2022년 7월 3일
0
post-thumbnail

Koin

Kotlin으로 DI를 공부하면서 가장 먼저 접하는 라이브러리는 kotlin DSL로 만들어진 Koin입니다.

Koin은 Dagger에 비해 구성요소가 복잡하지 Koin의 러닝커버는 다른 라이브러리보다 낮습니다.

DSL(Domain Specific Language) : 특정 도메인(산업, 분야등 특정 영역)에 국한해 사용하는 언어를 말합니다.

DSL 키워드

  • module : Koin 모듈 정의 (Module - 제공한 객체의 명세)
  • viewModel : Activity/Fragment에 각 ViewModel을 주입
  • factory : 의존성 주입(inject/get) 시점마다 새로운 객체를 매번 생성, Dagger의 Provide 같은 개념
  • single : 해당 객체를 싱글톤으로 생성(App Lifecycle 전체동안 단일 인스턴스)
  • bind() : Component 내에서 알맞은 의존성을 주입
  • inject() : get과 같이 알맞음 의존성을 주입(by inject() , val에만 가능, var 변수에 사용 불가)

Koin 동작 방식

  1. Module 선언(생성) - "Koin DSL"

  2. Application 단위 Class에서 startKoin()으로 Koin 실행

  3. 의존성 주입 - 구성요소 (Activity, Fragment, Class 등)

AppModule

Module은 객체를 제공하는 명세를 의미 factory, single , scoped 생성 문법 먼저 Module에서 제공할 의존성들의 클래스 구조를 선언해줍니다.

현재 제가 진행중인 프로젝트에서 사용되고 있는 코드들입니다.

val appModule = module {
	factory { (homeListCategory: HomeListCategory) ->
        HomeListViewModel(homeListCategory, get())
   	 }
     viewModel { HomeMarketMenuViewModel(get()) }
     
     single<SuggestRepository> {DefaultSuggestRepository()}

single : 싱글톤으로 생성해서 의존성주입(App 수명주기 동안 단일 인스턴스)

factory : 요청(Inject, get) 시점마다 새로운 인스턴스를 생성(Dagger의 Provider 개념)
객체 생성자 파라미터로 get()을 넣어줍니다.

App 레벨에서 Koin Start (Koin 초기화)

Application 단위 Class에서 Koin Start를 하기 위해 Application Class 선언

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        appContext = this

        startKoin {
            androidLogger(Level.ERROR) // AndroidLogger를 Koin logger로 사용합니다. 
            androidContext(this@MyApplication)
             modules(listOf(appModule,viewModelModule,repositoryModule))
       	 }
   	}
}

MainActivity(HomeFragment)

class HomeMainFragment
    : BaseFragment<FragmentHomeMainBinding>(),
    AdapterView.OnItemSelectedListener {
 private val resourcesProvider by inject<ResourcesProvider>()
    private val viewModel by viewModel<HomeMainViewModel>()
 }

single, factory는 by inject() 또는 get()을 사용해 Activity/Fragment에서 의존성을 주입하고

ViewModel은 by viewModel()을 사용해 의존성을 주입합니다.

ViewModel의 데이터를 공유받고 싶다면 sharedViewModel<>

private val activityViewModel by sharedViewModel<MainViewModel>()

Koin의 장단점

Koin은 리플렉션을 이용해 런타임에 오브젝트 그래프를 그려주다 보니(=의존성 주입을 하다보니) 앱 성능이 저하된다는 점이 있습니다. (실제로 회사들의 기술블로그를 본다면 Koin을 사용하다 Dagger-Hilt로 전환하는 곳도 많았습니다.)

그렇기에 큰 규모의 프로젝트에서는 Koin을 사용할 경우 Application이 시작될 때 의존성 그래프가 그려지다 보니 화면이 멈춘 것처럼 될 수 있다. 따라서 큰 규모의 프로젝트에서는 Dagger-Hilt을 이용해 의존성을 주입하는 것이 좋습니다.

Koin vs Dagger

Run time
-> Koin : 의존성 주입(영향 있음)
-> Dagger : 영향 없음

Compile Time
-> Koin : 영향 없음
-> Dagger : 의존성 주입

profile
Android 개발 잘하고 싶어요!!!

0개의 댓글