07
05

# Binding?

flowchart LR
    Android -->|Compile, Request| Hilt
    Hilt -->|Runtime, Inject| Android
    AppModule ---> Hilt
    NetworkModule ---> Hilt

์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ํ–‰์œ„๋‚˜ ๊ฐœ๋ณ„์ ์ธ ์ธ์Šคํ„ด์Šค dependency(Inject๋กœ ๋˜์–ด์žˆ๋Š”) ๋ชจ๋‘ ๋ฐ”์ธ๋”ฉ์ด๋ผ๊ณ  ํ•œ๋‹ค. ๊ทธ๋ƒฅ ์˜์กด์„ฑ์„ ๋ฐ”๋กœ ๊ฝ‚์„ ์ˆ˜๋„ ์žˆ๊ณ , ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•  ๋ชจ๋“ˆ์„ ๋‘ฌ์„œ ๋ชจ๋“ˆ์„ HiltComponent์— ๊ฝ‚์•„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

# Dependency Injection - ์ƒ์„ฑ์ž ์ฃผ์ž…, ํ•„๋“œ ์ฃผ์ž…, ๋ฉ”์„œ๋“œ ์ฃผ์ž…

// ์ƒ์„ฑ์ž ์ฃผ์ž…
class Test @Inject constructor(foo: Foo){ // foo ์ฃผ์ž…๊ณผ ๋™์‹œ์— Test ๋ฐ”์ธ๋”ฉ
 
}
// ํ•„๋“œ ์ฃผ์ž…
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject // ์–˜๋Š” ์š”์ฒญํ•ด์„œ ์ฃผ์ž… ๋ฐ›๋Š” ๊ฒƒ
    lateinit var test: Test
    ...
}
// ๋ฉ”์„œ๋“œ ์ฃผ์ž…
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    
    @Inject
    fun foo(bar: Bar){
	...
}

์ƒ์„ฑ์ž ์ฃผ์ž…๊ณผ ํ•„๋“œ์ฃผ์ž…์€ ์ด์ „ ๊ฒŒ์‹œ๊ธ€์—์„œ ํ™•์ธํ–ˆ๋‹ค. ๋ฉ”์„œ๋“œ ์ฃผ์ž…๋งŒ ๋ณด๋ฉด ๋˜๋Š”๋ฐ, foo ๋ฉ”์„œ๋“œ๋Š” bar๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๊ฒŒ ๋œ๋‹ค.

 

์ƒ์„ฑ์ž ์ฃผ์ž…์€ ๋”ฐ๋กœ ์Šค์ฝ”ํ”„ ์—†์ด Injectํ•ด๋ฒ„๋ฆฌ๋Š”๋ฐ ์ด ๊ฒฝ์šฐ Test ํด๋ž˜์Šค ์ž์ฒด๋„ ์ปดํŒŒ์ผ ํƒ€์ž„์— Hilt ์ปดํฌ๋„ŒํŠธ์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค๋Š” ํŠน์ด์ ์ด ์žˆ๋‹ค.  ๋ฉ”์„œ๋“œ ์ฃผ์ž…์€ Inject๊ฐ€ `super.onCreate` ์ดํ›„์— ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์„œ๋“œ์—์„œ lateinit var๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

lateinit var fooFun: Foo

@Inject // method ์ฃผ์ž…
fun provideFoo(foo: Foo){ // super.onCreate ์ดํ›„์— Inject๋˜์–ด fooFun์€ ์ดˆ๊ธฐํ™” ๋œ ์ƒํƒœ๋กœ ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๋‹ค.
    fooFun = foo
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    assert(this::fooFun.isInitialized) // true์ด๊ธฐ ๋•Œ๋ฌธ์— crash ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
	...
}

๊ทผ๋ฐ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ ์ฃผ์ž…์€ ์•„๋ฌด๋ž˜๋„ ์‚ฌ์šฉํ•˜๋Š” ๋นˆ๋„๊ฐ€ ์ ์„ ๊ฒƒ ๊ฐ™๋‹ค.

# `@Qualifier` , `@Named("์‹๋ณ„๋ช…")`

Hilt๋Š” ํƒ€์ž…์„ ๊ธฐ์ค€์œผ๋กœ ์˜์กด์„ฑ์„ ๊ตฌ๋ถ„ํ•˜๋Š”๋ฐ ๊ทธ๋ž˜์„œ ์ค‘๋ณต ๋ฐ”์ธ๋”ฉ์ด ๋ฐœ์ƒํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋™์ผํ•œ ํƒ€์ž…์˜ ๋‘ ์˜์กด์„ฑ์„ ๊ตฌ๋ถ„ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. -> `Dagger/DuplicateBindings` ๋กœ ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜จ๋‹ค. ๊ทผ๋ฐ ํƒ€์ž…์€ ๋™์ผํ•˜์ง€๋งŒ ์—ญํ• ์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘ ์‚ด๋ ค์•ผํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด Access Token์œผ๋กœ ์ ‘๊ทผํ•ด์•ผ ๋˜๋Š” ์˜์กด์„ฑ๊ณผ ๊ทธ๊ฒŒ ์—†์–ด๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์˜์กด์„ฑ ์ด๋ ‡๊ฒŒ ๋‘๊ฐœ๋กœ ๋‚˜๋ˆŒ ๋•Œ๊ฐ€ ๊ทธ ์˜ˆ์‹œ๋‹ค.  ์ด ๊ฒฝ์šฐ Qualifier๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ์€๊ทผํžˆ ๊ฐ„๋‹จํ•˜๋‹ค.

@Qualifier
annotation class TestQualifier
@Module
@InstallIn(SingletonComponent::class)
object TestModule {

    @Provides
    fun provideTest(): Test {
        return Test(id = "Test")
    }

    @TestQualifier
    @Provides
    fun provideTest2(): Test {
        return Test(id = "TestQualifier")
    }
}

Qualifer ์–ด๋…ธํ…Œ์ด์…˜์„ ๋‹ฌ๊ณ ์žˆ๋Š” ์ปค์Šคํ…€ Qualifier annotation์„ ๋งŒ๋“ค๊ณ , ๊ทธ๊ฑธ ์ค‘๋ณต๋ฐ”์ธ๋”ฉ์ด ํ•„์š”ํ•œ ๊ณณ์— ๋‹ฌ์•„์ฃผ๋ฉด ๋œ๋‹ค.

@Inject
lateinit var test1: Test

@TestQualifier
@Inject
lateinit var test2: Test

// ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ๊ฒฝ์šฐ
@Inject
fun injectTest(@TestQualifier test: Test){
    testQualifier = test
}

๋ฌผ๋ก  ์ฃผ์ž…๋ฐ›์„ ๊ณณ์—๋„ ๋‹ฌ์•„์ค˜์•ผ๋œ๋‹ค.

๊ป๋ฐ๊ธฐ๋งŒ ๋งŒ๋“ค์–ด๋‘๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์†์„ฑ์„ ์ •์˜ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

@Qualifier
annotation class TestQualifier(val id: String)

์ด๋ ‡๊ฒŒ ์ •์˜ํ•˜๋ฉด Inject๋‚˜ ๋ฐ”์ธ๋”ฉ ํ•  ๋•Œ ์†์„ฑ๊ฐ’์ธ key๋ฅผ ๋ช…์‹œํ•ด์ค˜์•ผํ•œ๋‹ค.

์ด๋Ÿฐ ์‹๋ณ„๊ณผ์ •์„ ์ข€ ๋” ์‰ฝ๊ฒŒํ•˜๋Š” ๋ฐฉ๋ฒ•์ด `@Named`์ธ๋ฐ ์‹๋ณ„๋ช… ๋ฌธ์ž์—ด์„ id๋กœ ๊ฐ–๋Š” Qualifier๋ผ๊ณ  ๋ณด๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
object TestModule {

//    @TestQualifier
    @Named("Test")
    @Provides
    fun provideTest2(): Test {
        return Test(id = "TestQualifier")
    }
}

ํ•œ ๋ฐ ๋ชจ์•„ ๊ด€๋ฆฌํ•˜๊ธธ ์ข‹์•„ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์•„๋งˆ Named ๋ณด๋‹ค Qualifier๋ฅผ ์„ ํ˜ธํ•˜์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ•œ๋‹ค.

# Lazy์™€ Provider

Hilt์˜ Lazy ์ฃผ์ž…์€ by lazy๊ณผ ํŠน์ •์‹œ์ ์— ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์ ์—์„œ ์•ฝ๊ฐ„ ๋น„์Šทํ•˜๋‹ค. ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์‹œ์ ์„ ์กฐ์ ˆํ•œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์ƒ์„ฑ๋น„์šฉ์ด ์ปค์„œ ์ด๊ฑธ ์กฐ์ ˆํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋„ ๋  ์ˆ˜ ์žˆ๋‹ค.

@Inject
lateinit var foo: Lazy<Foo> // Lazy

...
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    assert(foo.get().bar != null)

get์œผ๋กœ Lazy ์ฃผ์ž…์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ฃผ์˜ํ•  ์ ์€ Lazy๊ฐ€ dagger ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒ€์ž…์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ์ฝ”ํ‹€๋ฆฐ๋„ Lazy๋ฅผ ๊ฐ–๊ณ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— import๋ฅผ ์ž˜๋ชปํ•˜๋ฉด get์œผ๋กœ ๋ชป๊ฐ€์ ธ์˜จ๋‹ค.

Lazy๋กœ ์„ ์–ธํ•œ ์ธ์Šคํ„ด์Šค๋Š” ํ•œ๋ฒˆ ์ฃผ์ž…๋˜๋ฉด ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

@Inject
lateinit var fooProvider: Provider<Foo>

Provider๋„ ๋น„์Šทํ•˜๋‹ค. get์œผ๋กœ ๊ฐ€์ ธ์˜ค๊ณ , ํ˜ธ์ถœํ•  ๋•Œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. Lazy์™€ ๋‹ค๋ฅธ ์ ์€ Lazy๋Š” ํ•œ๋ฒˆ ์ƒ์„ฑ๋˜๋ฉด ๊ทธ๊ฑธ ๊ฐ€์ ธ์˜ค๋Š” ๊ฑฐ๊ณ , Provider๋Š” ๋งค ํ˜ธ์ถœ๋งˆ๋‹ค ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ ํ˜ธ์ถœ์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด Scope๋ฅผ ์ง€์ •ํ•ด์„œ(`@Singleton`์„ ๋ถ™์ธ๋‹ค๋˜๊ฐ€) ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•ด์•ผ๋œ๋‹ค.

# ๋ฐ”์ธ๋”ฉ ๊ธฐ๋ฒ• - `@Binds`

๋ฐ”์ธ๋”ฉ์€ DI ๊ทธ ์ž์ฒด(์ปดํฌ๋„ŒํŠธ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ํ–‰์œ„) ๋˜๋Š” ๊ทธ ์˜์กด์„ฑ ์ž์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

๋ชจ๋“ˆ ์•ˆ์—์„œ ์ปดํฌ๋„ŒํŠธ์— ๋‹ฌ์•„๋†“๋Š” `@Provides`๋Š” ์ด์ œ ์ต์ˆ™ํ•ด์กŒ๋‹ค. ๊ธฐ์กด์— Provide ๋œ ๋ฐ”์ธ๋”ฉ์ด ์žˆ์œผ๋ฉด `@Binds`๋กœ ํšจ์œจ์ ์œผ๋กœ ๋‹ฌ์•„ ๋‘˜ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. Binds๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ ๋Š” ์–ธ์–ด ํŠน์„ฑ์ƒ ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์œผ๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜์— ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ๋ฐ”์ธ๋”ฉ์„ ๊ฑธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ฆ‰ `@Binds`๋Š” ์ด๋ฏธ ๋ฐ”์ธ๋”ฉ ๋œ ์˜์กด์„ฑ์„ ํ™•์žฅ๊ด€๊ณ„์— ์žˆ๋Š” ์ƒˆ ํƒ€์ž…์œผ๋กœ ๊ฐ์‹ธ์„œ(์„ ํƒ์ ์œผ๋กœ ๋ชจ๋“ˆ ์„ค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค) ๋ฐ”์ธ๋”ฉ ์‹œํ‚ฌ ๋•Œ ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ œ์•ฝ ์กฐ๊ฑด์ด ์กด์žฌํ•˜๋Š”๋ฐ,

  1. `@Binds`๋Š” ๋ชจ๋“ˆ ๋‚ด abstract ๋ฉ”์„œ๋“œ์— ์ถ”๊ฐ€๋ผ์•ผํ•œ๋‹ค.
  2. ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•œ ๊ฐœ๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
  3. ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์ด ๋ฐ˜ํ™˜ ํƒ€์ž…์˜ ์„œ๋ธŒํƒ€์ž…์ด์–ด์•ผ ํ•œ๋‹ค.
  4. `@Scope` ๋ฐ `@Qualifier` ๋ž‘ ๊ฐ™์ด ์“ธ ์ˆ˜ ์žˆ๋‹ค. 

1, 2, 3 ๋ชจ๋‘ ํ™•์žฅ์ด ์šฉ์ดํ•œ ์–ธ์–ดํŠน์„ฑ์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜์˜ํ•œ ์กฐ๊ฑด๋“ค์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

abstract ๋ฉ”์„œ๋“œ๋Š” ๊ตฌํ˜„์ฒด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ผ ์ด๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋Š”๋ฐ, provides๋Š” ๊ทธ๊ฒŒ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์•ผ๋œ๋‹ค.(ํŒŒ์ผ ์ž์ฒด๋ฅผ ๋ถ„๋ฆฌ ์‹œ์ผœ๋ฒ„๋ฆฌ๋Š” ๊ฒŒ ์ข‹๋‹ค.) ๋„ค์ด๋ฐ๊ทœ์น™์€ `bind์„œ๋ธŒํƒ€์ž…`์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
// Binds๋ฅผ ์œ„ํ•œ ์ถ”์ƒ ๋ชจ๋“ˆ์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค
abstract class EngineModule {
    @Binds
    abstract fun bindGasolineEngine(engine: GasolineEngine): Engine

    @Binds
    abstract fun bindDieselEngine(engine: DieselEngine): Engine
}

Engine์€ ์ธํ„ฐํŽ˜์ด์Šค๊ณ , GasolineEngine, DieselEngine์€ ์ƒ์„ฑ์ž ๋ฐ”์ธ๋”ฉ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์— ๋‹ฌ๋ ค์žˆ๋Š” ์ƒํƒœ๋‹ค. ์ด๋Œ€๋กœ๋งŒ ๋†”๋‘๋ฉด Engine์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒŒ ์ค‘๋ณต๋ผ์„œ ์ค‘๋ณต๋ฐ”์ธ๋”ฉ์„ ํ—ˆ์šฉํ•˜์ง€์•Š๋Š” Hilt ํŠน์„ฑ์ƒ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. Named๋‚˜ Qualifier๋กœ ํ•ด๊ฒฐํ•˜๋ฉด ๋˜๋Š” ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฑด ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

 

# ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ  `@BindsOptionalOf`

๋ฐ”์ธ๋”ฉ ๋˜์–ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋Š” ์˜์กด์„ฑ์„ ์š”์ฒญํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ์˜ต์…”๋„์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”์ธ๋”ฉ ๋˜์ง€์•Š์•„๋„ ์ผ๋‹จ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐ”์ธ๋”ฉ์ด ์•ˆ๋œ ๊ฒฝ์šฐ๋„ ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋ฉด ์•ˆ๋œ๋‹ค. ๋˜ ๋ฐ›์•„์˜ฌ ์˜์กด์„ฑ๋„ Optionalํ•ด์•ผ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ž ๋ฐ”์ธ๋”ฉ ๋œ ์˜์กด์„ฑ๋“ค์€ ์ด๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

@Provides
fun provideFoo(): Foo{
    return Foo()
}

๊ทธ๋ž˜์„œ BindsOptionalOf๋Š” ๋”ฐ๋กœ provide๋œ ์˜์กด์„ฑ์„ ๋‹ฌ์•„์ค˜์•ผ๋œ๋‹ค.

@BindsOptionalOf
abstract fun bindDieselEngine(): Engine

์ด๋ ‡๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ง๊ณ  ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„ ์ƒ์˜ ๊ด€๊ณ„์—์„œ ๋ชจ๋‘ `Optional<T>`๋กœ ์„ ์–ธํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.

@Inject
lateinit var foo: Optional<Foo>

BindsOptionalOf๋กœ ๋ฐ”์ธ๋”ฉ ๋œ ์˜์กด์„ฑ์„ ์š”์ฒญํ•  ๋•Œ๋Š” Optional๋กœ ๊ฐ์‹ธ์„œ ํ•ด์ฃผ๊ณ ,  get()์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.

๋ฐ”์ธ๋”ฉ ๋˜์ง€์•Š์•˜๋‹ค๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— isPresent๋กœ ์ฒดํฌํ•ด์ค˜์•ผ๋œ๋‹ค. 

`@BindsInstance`๋Š” ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ๊ณผ ๋™์‹œ์— ๋ฐ”์ธ๋”ฉ ๋˜๋Š” ๊ฑธ ๋งํ•œ๋‹ค. ๊ทผ๋ฐ ์ด๊ฑด ๋”ฐ๋กœ ์™ธ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค...

 

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

 

๋ฐ˜์‘ํ˜•
COMMENT