#1 이전 글
위 게시글의 완성된 앱을 일부 수정해서, Interface를 Dependency로 주입해본다.
#2 코드 수정 - 직관적인 버전
#2-1 개요
위 게시글의 앱을 구현할 줄 안다면, 쉬운 구현 방식이다. Battery 클래스를 인터페이스로 바꾸고, 해당 인터페이스를 구현하는 EcoFriendlyBattery 클래스를 만든다. 그리고 EcoFriendlyBattery를 Dependency로 받고, Battery를 필요로 하는 Dependent에게 반환하는 @Provides 메소드를 만들면 끝이다. 본 게시글에선 @Component.Builder를 따로 작성하지 않는데, 왜냐하면 아래에 나와 있는 의존성 그래프에서 보듯, @Provides 메소드가 요구하는 Dependency가 @Inject에 의해 자동 주입되기 때문이다.
#2-2 의존성 그래프
이 경우의 의존성 그래프다.
#2-3 Battery.kt 수정
// package com.example.interfacedependency
interface Battery {
fun startBattery()
}
#2-4 EcoFriendlyBattery.kt 생성
// package com.example.interfacedependency
import android.util.Log
import javax.inject.Inject
class EcoFriendlyBattery @Inject constructor() : Battery {
override fun startBattery() {
Log.i("interfacer_han", "${this::class.simpleName} is ready")
}
}
#2-5 @Module 클래스 및 @Provide 메소드 생성
// package com.example.interfacedependency
import dagger.Module
import dagger.Provides
@Module
class BatteryModule {
@Provides
fun providesEcoFriendlyBattery(ecoFriendlyBattery: EcoFriendlyBattery): Battery {
return ecoFriendlyBattery
}
}
#2-6 @Component에 @Module 등록
// package com.example.interfacedependency
import dagger.Component
@Component(modules = [BatteryModule::class])
interface CarComponent {
fun getCar(): Car
}
#2-7 작동 확인 (로그 메시지)
Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
EcoFriendly
Battery is ready
Car is ready
#3 코드 수정 - @Binds 사용
#3-1 개요
@Binds 어노테이션을 이용해 #2를 수정해본다. @Binds는 dagger에서 인터페이스와 그 구현체를 바인딩하는 목적을 가진다. 이 어노테이션을 통해 프로그래머는 특정 인터페이스 타입인 Dependency를 어떤 구현체로 정할 지 명시할 수 있다.
#3-2 의존성 그래프
#2-2와 구조가 같다. 구현 방식이 더 간결해졌을 뿐이다.
#3-3 BatteryModule.kt 수정
...
@Module
abstract class BatteryModule {
@Binds
abstract fun bindsEcoFriendlyBattery(ecoFriendlyBattery: EcoFriendlyBattery): Battery
}
/*
@Module
class BatteryModule {
@Provides
fun providesEcoFriendlyBattery(ecoFriendlyBattery: EcoFriendlyBattery): Battery {
return ecoFriendlyBattery
}
}
*/
#2와 완전히 똑같이 수정하되, BatteryModule.kt만 위와 같이 바꾼다. @Binds 어노테이션은 설계상 문법적으로 반드시 추상 메소드에 붙는다. 어째서일까? @Binds는 이름 그대로 Binding이 목적이기에, 실제로 내부적으로 객체를 생성해 반환하는 비(非)추상 메소드와 함께할 이유가 없기 때문이다. 객체를 생성하는 게 아니라, 이미 생성된 객체(여기서는 EcoFriendlyBattery)를 (Battery에) 바인딩하는 게 @Binds 메소드의 역할이다.
또, 추상 메소드를 가지기 위해선 추상 클래스여야하므로 @Module 클래스를 추상 클래스로 만든다. dagger 라이브러리는 이러한 추상 @Module 클래스 안에는 반드시 @Binds 추상 메소드가 있을 거라고 인식하고 적절히 처리한다.
#3-4 작동 확인 (로그 메시지)
Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
EcoFriendly
Battery is ready
Car is ready
#4 요약
@Binds는 인터페이스 구현체를 의존성 주입하기 위한 어노테이션이다.
#5 완성된 앱
'깨알 개념 > Android' 카테고리의 다른 글
[Android] Dagger2 - Application 활용하기 (0) | 2024.06.25 |
---|---|
[Android] Dagger2 - Activity에 Dependency 주입 (0) | 2024.06.25 |
[Android] Dagger2 - 매개변수 동적 할당 (0) | 2024.06.24 |
[Android] Dagger2 - @Provides (0) | 2024.06.24 |
[Android] Dagger2 - 기초 (0) | 2024.06.24 |