일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 재택근무
- 테트리스
- 좌식테이블
- 소프시스 밤부 좌식 엑슬 테이블
- 목적 중심 리더십
- T자형인재
- 북한살둘레길
- 한달독서
- 함수형 프로그래밍
- 브런치작가되기
- 프래그먼트
- 면접
- 커스텀린트
- 어떻게 나답게 살 것인가
- 자취필수템
- 한단어의힘
- 캐치마인드
- 베드트레이
- 안드로이드
- 한달브런치북만들기
- 목적중심리더십
- 소프시스
- 슬기로운 온라인 게임
- 리얼하다
- 지지않는다는말
- 베드테이블
- 아비투스
- 한달어스
- 1일1커밋
- 끝말잇기
- Today
- Total
정상에서 IT를 외치다
[Dagger] Dagger step5 - Binds와 Multi binding 본문
안녕하세요. 블랙진입니다.
이번에는 binds와 multi binding에 대해 알아보는 시간을 가지겠습니다. 그전에! @Provides와 @Named 어노테이션을 사용해 다형화된 객체를 어떻게 불러오는지 혹은 같은 타입을 반환하는 함수를 어떻게 구분하는지 확인해 보겠습니다.
@Provides @Named 사용법
1. CoffeeBean을 추상화 하여 BlackBean과 WhiteBean을 각각 만들어 줍니다.
CoffeeBean
public interface CoffeeBean {
String name();
}
BlackBean
public class BlackBean implements CoffeeBean {
@Override
public String name() {
return "BlackBin";
}
}
WhiteBean
public class WhiteBean implements CoffeeBean {
@Override
public String name() {
return "WhiteBin";
}
}
2. Module에서 같은 타입이지만 다른 객체를 반환하는 함수를 만들어 줍니다. 이때 같은 타입을 반환 하므로 @Named 어노테이션을 사용해 구분해 주어야합니다.
@Module
public class CafeModule {
//...
@Named("black")
@Provides
CoffeeBean provideBlackCoffeeBean() {
return new BlackBean();
}
@Named("white")
@Provides
CoffeeBean provideWhiteCoffeeBean() {
return new WhiteBean();
}
}
3. Component에서 반환할 타입을 정해줍니다.
@Singleton
@Component(modules = CafeModule.class)
public interface CafeComponent {
CafeInfo cafeInfo();
@Named("black")
CoffeeBean blackCoffeeBean();
@Named("white")
CoffeeBean whiteCoffeeBean();
}
4. 사용예제
//카페를 생성합니다.
CafeComponent cafe = DaggerCafeComponent.create();
CafeInfo cafeInfo = cafe.cafeInfo();
cafeInfo.welcome();
System.out.println("bean : " + cafe.blackCoffeeBean().name());
System.out.println("bean : " + cafe.whiteCoffeeBean().name());
이렇게 같은 데이터 타입을 @Provides와 @Named를 사용해 보았습니다. 이번에는 binds와 multi binding을 사용해 구현해 보겠습니다,
@Provides와 @Binds 비교
이 둘 모두 Module에서 객체를 제공해주는 어노테이션입니다. 그럼 어떤 차이점을 가지고 있을까요? @Provides를 사용하면 @Binds 보다 비효율적인 코드들이 생성되게 됩니다. 약 40%이상 코드가 더 생성된다고 합니다. 그러니 효율적인 면에서 @Binds를 사용하면 좋겠지만 제약이 있습니다. @Binds 어노테이션은 오직 1개의 파라미터를 가지고 있어야 하며 abstract 함수로 호출해야 합니다. 더 자세한 설명은 @Binds vs @Provides를 확인해주세요 :)
Binds 사용방법
1. CafeModule을 abstract로 변경해줍니다. 이때 provides는 static으로 선언해서 사용해 주어야 합니다.
@Module
public abstract class CafeModule {
@Singleton
@Provides
static CafeInfo provideCafeInfo() {
return new CafeInfo("BlackJin");
}
@Binds
abstract CoffeeBean provideBlackCoffeeBean(BlackBean blackBean);
}
2. BlackBean의 @Inject를 추가해 줍니다.
public class BlackBean implements CoffeeBean {
@Inject
BlackBean() {
}
@Override
public String name() {
return "BlackBin";
}
}
이렇게 하면 CoffeeBean 객체를 BlackBean 이란 객체에 바인딩 하는 것을 의미합니다. 그럼 어떻게 가져와서 사용할까요?
3. 간결하게 CafeComponent에서 coffeeBean()을 가져와 사용하면 됩니다. (이 예제에서는 WhiteBean은 아직 생성하지 않았습니다.)
@Singleton
@Component(modules = CafeModule.class)
public interface CafeComponent {
CafeInfo cafeInfo();
CoffeeBean coffeeBean();
}
4. 사용예제
//카페를 생성합니다.
CafeComponent cafe = DaggerCafeComponent.create();
CafeInfo cafeInfo = cafe.cafeInfo();
cafeInfo.welcome();
System.out.println("bean : " + cafe.coffeeBean().name());
MultiBindin 적용하기
그럼 같은 타입을 반환하는 BlackBean과 WhiteBean을 구분해서 바인딩 해보겠습니다.
1. @IntroMap, @StringKey 를 적용해 Map 형태로 데이터를 받아옵니다.
@Module
public abstract class CafeModule {
//...
@Binds
@IntoMap
@StringKey("black")
abstract CoffeeBean provideBlackCoffeeBean(BlackBean blackBean);
@Binds
@IntoMap
@StringKey("white")
abstract CoffeeBean provideWhiteCoffeeBean(WhiteBean whiteBean);
}
2. CafeComponent 에서 Map<String, CoffeeBean> 반환 타입의 함수를 선언합니다.
@Singleton
@Component(modules = CafeModule.class)
public interface CafeComponent {
CafeInfo cafeInfo();
Map<String,CoffeeBean> coffeeBean();
}
3. 사용예제
//카페를 생성합니다.
CafeComponent cafe = DaggerCafeComponent.create();
CafeInfo cafeInfo = cafe.cafeInfo();
cafeInfo.welcome();
System.out.println("bean : " + cafe.coffeeBean().get("black").name());
System.out.println("bean : " + cafe.coffeeBean().get("white").name());
만약 key가 없는 값을 호출하게 되면 NullPointerException이 발생합니다.
예제에서 사용한 코드는 깃허브에서 볼 수 있습니다.
'안드로이드' 카테고리의 다른 글
[Android, FragmentFactory] framgnet에서 newInstance() 쓰지 말라고? (0) | 2020.03.18 |
---|---|
[Android, Proguard] 안드로이드 프로가드 설정하기 3 (0) | 2020.03.13 |
[Dagger] Dagger step4 - Module 초기화 (0) | 2020.02.11 |
카메라 예제와 함께 보는 Scoped Storage (안드로이드 Q 대응) (1) | 2020.01.13 |
카메라 예제와 함께 보는 Scoped Storage (이미지 가져오기) (0) | 2020.01.13 |