Dagger2 + Kotlin Example

Hanmolee
8 min readNov 22, 2018

Dagger2로 의존성 주입하는 예제입니다.

원래 목적은 Dagger2 -> AndroidDagger -> Koin 까지 직접 구현 및 실제 프로젝트에서 개발을 해 본 이후에 차이점들을 글로 작성하려고 했었다.

이번 회사 프로젝트 스프린트가 조금 빠듯할 듯 하여 아쉽게도 Koin까지의 스터디가 부족한 상태에서 글을 쓰게 되었다.

현재는 Dagger2 -> AndroidDagger 까지 스터디를 완료 하고 실제 회사 프로젝트에 도입을 마친 상태이다.

먼저 Dagger2를 사용해 의존성 주입을 하는 예제를 만들어 다른 사람들에게 도움이 되고자 한다.

Dagger2란?

Dagger2는 DI(Dependenct Injection) Framework Library입니다.

(좀더 구제적인 것을 원하신다면 구글링을 해주세요!)

DI란 외부에서 객체를 생성해서 넘겨주는 것이라고 생각하면 됩니다.

예를 들면 A객체를 외부에서 독립적으로 생성하여 A객체를 사용하고자 하는 곳에서 외부에서 생성된 A객체를 참조하는 것입니다.

즉 객체간의 결합도를 느슨하게 만들게 됩니다.

의존성 주입을 사용하여 프로그램을 구현하게 되면

재사용성과 테스트, 유지보수성에 좀 더 유연한 대처가 가능합니다.

실제로 사용하면서 재사용성, 유지보수성에 좀 더 효과적이라는 것을 직접 경험하였습니다.

테스트코드는 현재 진행중이며 Mock 객체와 실제 객체를 바꿔가며 테스트할 예정이며

유닛테스트 이외에도 Appium을 활용하여 테스트 자동화와 함께 스터디를 하고 있습니다.

제가 Dagger2를 도입한 가장 큰 목적으로는

MVP 패턴을 사용하기 위해 Presenter를 Activity에 주입시키려는 목적으로 사용하게 되었습니다.

Dagger 기본개념

Dagger2의 API가 존재합니다.

  1. @Inject : 의존성 주입을 요청
  2. @Component : Moule을 이용하여 의존성 객체를 생성하며 Inject로 요청받은 인스턴스에 생성된 객체를 주입하는 Module과 Inject 사이의 다리역할
  3. @SubComponent : Component의 하위 계층이라고 생각하면 됩니다. 처음 Inject로 주입을 요청받으면 SubComponet -> Component 순서로 의존성을 검색합니다.
  4. @Module : Componet에 연결되어 의존성을 제공하는 메서드들을 가진 객체를 생성
  5. @Provide : 모듈 내에서 언급된 의존성을 어떻게 구성 및 제공하는지 알려준다.
  6. @Scope : 의존성 관련 객체의 생명주기 범위, Module에서 Scope를 보고 객체를 관리 Ex> @ActivityScope, @FragmentScope

Dagger2 Tutorial

의존성 주입을 하여 버튼 이벤트로 주입된 객체의 함수를 사용하는 예제

1. Gradle 추가 [dagger2_version = 2.18]

apply plugin: 'kotlin-kapt'dependencies {
implementation "com.google.dagger:dagger:$dagger2_version"
kapt "com.google.dagger:dagger-compiler:$dagger2_version"
}

2. 의존성 객체를 생성한다.

  • Cat (고양이 이름이 있는 객체)
class Cat {

private val catName = "RegDoll"

fun getCatName(): String {
return catName
}
}
  • Dog (개 이름이 있는 객체)
class Dog {

private val dogName = "puddle"

fun getDogName(): String {
return dogName
}
}

3. Component에 연결되어 의존성 객체를 제공할 모듈을 만든다.

  • Cat 객체를 생성하여 제공할 모듈
@Module
object CatModule {

@Provides
fun provideCat() : Cat {
return Cat()
}

}
  1. singleTon으로 CatModule라는 모듈을 만들고 @Module 어노테이션을 붙여준다.
  2. Cat 객체 생성하여 return하는 함수를 만들고 @Provides 어노테이션을 붙여준다.
  • Dog 객체를 생성하여 제공할 모듈
@Module
object DogModule {

@Provides
fun provideDog() : Dog {
return Dog()
}

}
  1. singleTon으로 DogModule라는 모듈을 만들고 @Module 어노테이션을 붙여준다.
  2. Dog 객체 생성하여 return하는 함수를 만들고 @Provides 어노테이션을 붙여준다.

4. 모듈을 연결하여 의존성 객체를 생성하고 @Inject 로 요청받은 인스턴스에 의존성 객체를 주입하는 Component를 만든다.

  • Cat과 Dog 객체를 생성하여 제공시키는 모듈을 주입시키는 Component를 만든다.
@Singleton
@Component(modules = [DogModule::class, CatModule::class])
interface PetComponent {

fun inject(mainActivity: MainActivity)

@Component.Builder
interface Builder {

fun build() : PetComponent

fun dogModule(dogModule : DogModule) : Builder
fun catModule(catModule: CatModule) : Builder


}
}
  1. DogModule, CatModule을 Component에 연결시킨다.
  2. 연결된 모듈을 사용할 인스턴스(MainActivity)에 주입하는 Inject 함수를 만든다.
  3. MainActivity와의 연결을 도울 interface(Builder)를 만든다.

5. MainActivity에 의존성을 주입시켜 의존성 객체를 사용한다.

class MainActivity : AppCompatActivity() {

@Inject
lateinit var cat : Cat

@Inject
lateinit var dog: Dog

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

injectComponent()

setGetCatNameButton()
setGetDogNameButton()
}

private fun injectComponent() {
DaggerPetComponent.builder()
.catModule(CatModule)
.dogModule(DogModule)
.build()
.inject(this)
}

private fun setGetCatNameButton() {
catNameButton.setOnClickListener {
catNameText.text = cat.getCatName()
}
}
private fun setGetDogNameButton() {
dogNameButton.setOnClickListener {
dogNameText.text = dog.getDogName()
}
}


}
  1. @Inject 어노테이션을 사용해 의존성 객체를 주입한다.
  2. MainActivity가 생성될 때 Component를 연결합니다. (Dagger[Component Name]) 이 생성이 안되어 있을텐데 빌드를 한번 해야만 생성이 됩니다.)
  3. Component를 연결할 때 사용할 Module을 지정해 줍니다.
  4. inject(this) 하여 의존성 주입을 실행합니다.
  5. 4번의 과정을 거치게 되면 @Inject 어노테이션이 정의되어 있는 객체가 주입됩니다.
  6. button 이벤트가 발생하면 의존성 객체의 메서드를 사용하여 이름을 불러옵니다.
  7. MainActivity에서 Dog와 Cat을 생성하지 않고 메서드를 사용하는 것을 확인 할 수 있습니다.

- 의존성 주입과 함께 사용할 MVP 패턴 관련된 예제는 이곳에서 확인할 수 있습니다.

- 이 글의 Dagger2 관련 예제는 이곳에서 확인하실 수 있습니다.

감사합니다.

--

--