개발자이야기
android Dagger 본문
Dagger
DI(의존성주입)는 갈수록 비대해지는 프로젝트와 요구사항들과 수정사항들이 많아지는 요즘 개발 시장에서 계속해서 중요하게 다뤄지고 있습니다. (과거에는 제가 어려서 잘 모르겠습니다..)
Dagger는 팩토리패턴과 연관성이 깊습니다. 팩토리 패턴에 대해 추후 포스팅 해보겠습니다.
의존성주입이란? https://webprogramcustom.tistory.com/26
Dagger의 장점
1. 보일러 플레이트 코드를 줄여준다.
2. 스코프를 지정하여 각 클래스들의 생명주기나, 재사용을 하기가 편해진다.
3. 코드가 유연해진다.
4. 유닛테스트를 더 쉽게 작성할 수 있다.
위의 장점은 Dagger의 장점과 의존성주입 자체의 장점이 포함되어 있습니다.
Dagger사용법
Android 앱은 실행되는 동안 보통 Application은 살아있기 때문에 Application class 에서 Dagger 그래프를 만듭니다.
이렇게 되면 Dagger 그래프는 application 수명주기에 연결되게 됩니다.
그래프를 생성하는 인터페이스는 @Component로 어노테이션을 지정하여 호출하여 사용합니다.
ApplicationComponent
@Component(
modules = [//그래프를 연결한 모듈]
)
interface ApplicationComponent {...}
class MainApplication: Application() {
val appComponent: ApplicationComponent = DaggerApplicationComponent.create()
}
앞으로 application Dagger 그래프가 필요할때 application class 에 있는 appComponent 인스턴스를 호출하여 inject 하여 사용할 수 있습니다.
따라해보니 DaggerApplicationComponent.create() 함수가 없으신가요? 그럼 ApplicationComponent 인터페이스 까지 만들고 앱 빌드를 한번 진행 하시면 컴파일 과정에서 코드가 생성됩니다.
Activity inject
@Component(modules = [CarModule::class])
interface ApplicationComponent {
fun inject(activity: MainActivity) //Activity inject
}
MainActivity에서 주입을 받기 위해서는 Dagger 그래프에 액세스 해야 합니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
(applicationContext as MainApplication).appComponent.inject(this) //1. 그래프 액세스
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
1. MainActivity를 ApplicationComponent 인터페이스에 정의되어 있는 inject 함수를 이용하여 MainActivity 를 Dagger에 생성합니다. 이제 MainActivity 에서 Dagger로 부터 주입을 받을 준비가 끝났습니다.
Module
Module 을 이용하여 필드에 주입시켜 주는 provide 와 binds 에 대해 알아봅시다.
Provides
@Module
class CarModule {
@Provides
fun provideCar(): Avante {
return Avante()
}
}
@Provides어노테이션은 Dagger에게 인스턴스 만드는 방법을 알려줍니다.
단순히 객체를 인스턴스화 해 주는 방법입니다.
Binds
@Module
abstract class CarModule {
@Binds
abstract fun bindCar(avante: Avante): Car
}
@Binds 어노테이션은 사용 조건이 있습니다. abstract 함수를 사용해야 하며, 하나의 구현체를 인자로 받아야 합니다.
위의 함수의 return 타입은 Car 인터페이스 이며 파라미터로 Avante인 Car 구현체를 전달받고 있습니다.
interface Car {
fun getCar(): String
}
class Avante @Inject constructor() : Car {
override fun getCar(): String {
return "아반떼"
}
}
위의 Avante 클래스에서 @Inject constructor() 생성자 주입을 명시 해 줌으로써 Dagger 에게 주입을 알려 줄 수 있습니다.
class MainActivity : AppCompatActivity() {
@Inject lateinit var car: Car
override fun onCreate(savedInstanceState: Bundle?) {
(applicationContext as MainApplication).appComponent.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainText.text = car.getCar()
}
}
이제 위와같이 car 객체에는 Avante 인스턴스를 주입받을 수 있습니다.
Dagger 를 제대로 사용하려면 Dagger 에서 말하는 그래프 형식을 이해해야 합니다. 큰 틀의 ApplicationComponent를 시작으로 하위 subComponent들을 계층에 맞게 연결해서 사용해야 합니다.
간단한 Dagger 의 사용법을 알아봤습니다. SubComponent 들까지 사용하여 설명하려면 너무 방대해지는 포스트가 될거같아 간단한 사용법만을 포스팅 합니다.
궁금하신점은 말씀해주시고 잘못된 점은 지적부탁드립니다. 읽어주셔서 감사합니다.
'android' 카테고리의 다른 글
android launchMode (0) | 2021.07.13 |
---|---|
android 수명주기 (0) | 2021.07.08 |
mvvm + dagger (0) | 2021.06.07 |
android AAC LiveData - switchMap, map (0) | 2021.05.28 |
dagger @binds 어노테이션 (1) | 2021.05.23 |