07
05

# ๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ `@IntoSet` `@IntoMap` `@Multibinds`

๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ์€ ์—ฌ๋Ÿฌ ๋ฐ”์ธ๋”ฉ์„ ํ•˜๋‚˜์˜ ์ปฌ๋ ‰์…˜์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ๋‹ค. Set, Map ์ปฌ๋ ‰์…˜์„ ์ง€์›ํ•˜๋ฉฐ  ์ค‘๋ณต๋ฐ”์ธ๋”ฉ์ด๋ž‘์€ ๊ฒฐ์ด ์ข€ ๋‹ค๋ฅด๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. 

Set์„ ์ด์šฉํ•œ ๋ฐฉ์‹์€ ๊ธฐ์กด @Providesํ•˜๋˜ ๋ฐ”์ธ๋”ฉ์— `@IntoSet`์„ ๋‹ฌ์•„์ฃผ๋ฉด ๋œ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํŒŒ์ผ ํƒ€์ž„์—์„œ Set์•ˆ์— @IntoSet์ด ์„ ์–ธ๋œ ๋ฐ”์ธ๋”ฉ์„ ๋ฌถ์–ด์„œ ๊ฐ–๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค. ๊ทผ๋ฐ ์ปฌ๋ ‰์…˜์œผ๋กœ ๋ฐ”์ธ๋”ฉ์„ ๊ด€๋ฆฌํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•˜๋‚˜ ์ƒ๊ธด๋‹ค.

 

๋‹จ๋… ๋ฐ”์ธ๋”ฉ์ผ ๋•Œ๋Š” EntryPoint์—์„œ @Injectํ•  ๋•Œ ์•Œ์•„์„œ ๊ฐ€์ ธ๊ฐ”๋Š”๋ฐ, ๋ฐ˜ํ™˜ํƒ€์ž…์ด Set<T>์œผ๋กœ ๊ฐ์‹ธ์ ธ์žˆ์–ด์„œ ๊ทธ๋ƒฅ @Injectํ•˜๋ฉด MissingBinding์„ ์˜ค๋ฅ˜๋กœ ๋‚ด๋ฟœ๊ฒŒ ๋œ๋‹ค.

 

๋‹จ๋… ๋ฐ”์ธ๋”ฉ์ด Set<T>์œผ๋กœ ๋˜์–ด์žˆ๋‹ค๋ฉด @IntoSet๋ง๊ณ  `@ElementsIntoSet`์„ ๋‹ฌ์•„์ค˜์•ผ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋‹จ๋… ๋ฐ”์ธ๋”ฉ ๋œ Set์˜ ์›์†Œ๋“ค์ด Set ๋ฉ€ํ‹ฐ ๋ฐ”์ธ๋”ฉ ๋ผ์„œ ๋“ค์–ด์˜จ๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
class MultiBindModule {
    @Provides
    @IntoSet
    fun provideString(): String{
        return "test"
    }
}

// ์‚ฌ์šฉ์€ ์•„๋ž˜์ฒ˜๋Ÿผ Set์œผ๋กœ
@Inject
lateinit var str: Set<String>

Set์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ”์ธ๋”ฉ์„ ์“ด ๊ฑด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
class MultiBindModule {
    @Provides
    @IntoSet
    fun provideString(): String {
        return "test"
    }

    @Provides
    @ElementsIntoSet
    fun provideStrings(): Set<String> {
        return setOf("a", "b", "c")
    }
}

๊ทธ๋Ÿผ ์œ„์—์„œ str์€ Set์„ ๋ฐ›์•„์˜ค๋Š”๋ฐ, ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‚˜์˜ฌ๊นŒ?

๋‹ค ๋‹ด๊ฒจ์„œ ๋“ค์–ด์˜จ๋‹ค. Set ๋ง๊ณ  Map์œผ๋กœ๋„ ๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Map์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Key - Value ํ˜•์‹์ด๋ผ ํ‚ค๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผํ•˜๋Š”๋ฐ, String, Int, Long, Class๋กœ ํ‚ค๋ฅผ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ Set๊ณผ ๋น„์Šทํ•œ๋ฐ, @IntoMap๊ณผ @"ํƒ€์ž…"Key("ํ‚ค ๊ฐ’")์„ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

@Provides
@IntoMap @IntKey(1)
fun provideName(): String{
    return "one"
}

@Provides
@IntoMap @ClassKey(Test::class)
fun provideNameOfClass(): String{
    return "Test Value"
}

Testํด๋ž˜์Šค๋ฅผ ํ‚ค๋กœ ์“ด๊ฑด๋ฐ ํ‚ค ํƒ€์ž…์ด `Class<*>`๊ฐ€ ๋œ๋‹ค. Map์„ ์‚ฌ์šฉํ•œ ๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ์€ ํ‚ค๊ฐ’์ด ๊ฐ€์žฅ ์ค‘์š”ํ•ด์„œ ์กฐ์‹ฌํ•ด์•ผ๋œ๋‹ค.

@Inject
lateinit var mapInt: Map<Int, String>

@Inject
lateinit var mapClass: Map<Class<*>, String>

mapClass ๊ฐ’์€ `mapClass[Test::class.java]`๋กœ ๊บผ๋‚ด์“ด๋‹ค.

 

์ง€์ •๋œ ํƒ€์ž… ๋ง๊ณ ๋„ ํ‚ค๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. `@MapKey`๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ์‹์ธ๋ฐ ํ‚ค๊ฐ€ ๋  enum class ๊ฐ™์€ ๊ฑธ annotation class๋กœ ์ปค์Šคํ…€ ํ‚ค ์–ด๋…ธํ…Œ์ด์…˜ ์„ ์–ธํ•ด์ฃผ๊ณ , @MapKey๋ฅผ ๋ถ™์—ฌ์„œ ์“ฐ๋ฉด๋œ๋‹ค.

@MapKey
annotation class CustomMapKey(val value: Keys)

enum class Keys {
    ONE,
    TWO,
    THREE
}

// ๋ชจ๋“ˆ์—์„œ๋Š” ์•„๋ž˜ ์ฒ˜๋Ÿผ
@Provides
@IntoMap
@CustomMapKey(Keys.ONE)
fun provideCK(): String{
    return "CK"
}

Inject ๋ถ€๋ถ„์—์„œ๋Š” Enum ํด๋ž˜์Šค๋ฅผ Key์— ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

 

`@Multibinds`๋Š” ๋ฐ”์ธ๋”ฉ ๋œ์ง€ ์•ˆ๋œ์ง€ ๋ชจ๋ฅด๋Š” ์ƒํƒœ์ด๊ฑฐ๋‚˜ ๋นˆ์ปฌ๋ ‰์…˜์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

 

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”!

 

๋ฐ˜์‘ํ˜•
COMMENT