#1 ์ด์ ๊ธ
[Android] Dagger2 - ๊ธฐ์ด
#1 ์ด์ ๊ธ ์์กด์ฑ ์ฃผ์ (Dependency Injection)#1 ์์กด์ฑ ์ฃผ์ (Dependency Injection)์ด๋?#1-1 Dependent์ Dependencyfun main() { val car = Car() car.startCar() } class Car { private val engine = Engine() private val airbag = Airbag() private
kenel.tistory.com
์ ๊ฒ์๊ธ์ ์์ฑ๋ ์ฑ์ ์ผ๋ถ ์์ ํด์, @Inject๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ์ ์์กด์ฑ ์ฃผ์
์ ํด๊ฒฐํด๋ณธ๋ค.
#2 @Provides
์ด์ ๊ธ์์ ์์ฑ์์ @Inject๋ฅผ ๋ถ์๊ณ , ๊ทธ๊ฒ์ dagger๊ฐ ์์กด์ฑ ์ฃผ์
์ ํ๋ ๋ช
์์ ์ธ ํ์๋ก์ ์๋ํ๋ค. ํ์ง๋ง, ์์ฑ์์ @Inject๋ฅผ ๋ถ์ธ๋ค๋ ๊ฒ์ ๊ทธ ํ๋์ ๋ฒ์๊ฐ ์ฌ์ฉ์ ์ ์ ํด๋์ค๋ก ์ ํ๋๋ค๋ ๋ง์ด๊ธฐ๋ ํ๋ค. ์ฌ์ฉ์ ์ ์ ํด๋์ค๊ฐ ์๋ ๊ฒ์ ๋ฌด์์ผ๊น? String, Int ๋ฑ๊ณผ ๊ฐ์ ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ถํฐ Retrofit, Room ๋ฑ ์ 3์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค. ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ง๋ค์ด์ง ํด๋น ํด๋์ค๋ค์ ์์ ํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ฉฐ, ์ค๋ น ๊ฐ๋ฅํ๋ค๊ณ ํด๋ ๊ทธ ๋ฐฉ๋ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฑด๋ค์ด๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์์ ๊ฒ์ด๋ค.
์ด๋ด ๋ @Inject ๋์ ์ฌ์ฉํ๋ ๊ฒ์ด @Provides๋ค. ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ด๊ฒ ์ ๊ณต(Provides)๋ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ ๊ฒ์ด ๋ชฉ์ ์ด๋ค.
์ถ๊ฐ๋ก, @Inject๋ก ์์กด์ฑ ์ฃผ์
์ ํ๋ ๊ฒ์ด ์ด๋ก ์ ๊ฐ๋ฅํจ์๋ @Provides๋ฅผ ์ ํํด ์ฐ๋ ๊ฒฝ์ฐ๋ ์๋ค. ๋ฐ๋ก, ์ธ์คํด์ค ์์ฑ์ ๋ณต์กํ ๋ก์ง์ด ํ์ํ ๊ฒฝ์ฐ๊ฐ ๊ทธ๋ ๋ค.
#3 ์ฝ๋ ์์ - @Provides ์ฌ์ฉ
#3-1 Dependency ์ถ๊ฐ

์์ ๊ฐ์ด ๊ธฐ์กด ์์กด์ฑ ๊ทธ๋ํ์์ Airbag์ด Stringํ์ธ Dependency๋ฅผ ์๊ตฌํ๊ฒ ๋ง๋ ๋ค. String์ ์ฝ๊ธฐ ์ ์ฉ ํด๋์ค๋ค. ์ฆ, @Provides๋ก ์ ๊ณต๋์ด์ผ ํ๋ค.
// package com.example.provides
import android.util.Log
import javax.inject.Inject
class Airbag @Inject constructor(private val manufacturer: String) {
fun startAirbag() {
Log.i("interfacer_han", "${this::class.simpleName} is ready")
Log.i("interfacer_han", "${this::class.simpleName} made by ${manufacturer}")
}
}
Airbag ํด๋์ค์ ์ฝ๋๋ ์ด ์ ๋๋ก ์์ ํ๋ค.
#3-2 @Module
// package com.example.provides
import dagger.Module
@Module
class MyModule {
// TODO: @Provides ๋ฉ์๋ ๋ง๋ค๊ธฐ
}
์ด์ ๊ธ์ ์ํ๋ฉด, @Component ํด๋์ค๋ ํ๋ก์ ํธ๋ฅผ ์ค์บํ๋ฉฐ @Inject๊ฐ ๋ถ์ ์์ฑ์๋ @Provides๊ฐ ๋ถ์ ๋ฉ์๋๋ฅผ ์ฐพ๋๋ค. ์์์ ์์กด์ฑ ์ฃผ์
์ ํ๋ ์ฃผ์ฒด๊ฐ @Component ํด๋์ค์ด๊ธฐ ๋๋ฌธ์ด๋ค. @Provides ๋ฉ์๋๋ ๋ฐ๋์๋ ์๋์ง๋ง ๊ฑฐ์ ๋๋ถ๋ถ @Module ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค ๋ด๋ถ์ ์ ์๋๋ค. @Module ์ญํ ์ ํ ํด๋์ค๋ฅผ ๋ง๋ ๋ค.
#3-3 @Component
// package com.example.provides
import dagger.Component
@Component(modules = [MyModule::class])
interface CarComponent {
fun getCar(): Car
}
Component ์ธํฐํ์ด์ค์ @Module ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ค. ์ด ์์ ๋ถํฐ, Component ํด๋์ค๋ ์์กด์ฑ ์ฃผ์
์ ์ํ @Inject ๋ฐ @Provides์ ์ค์บ ๋ฒ์์ MyModule ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ค.
#3-4 @Provides
// package com.example.provides
import dagger.Module
import dagger.Provides
@Module
class MyModule {
@Provides
fun providesAirbagManufacturer(): String {
return "KENEL"
}
}
MyModule ํด๋์ค์ String์ ๋ฐํํ๋ ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
#3-5 ์๋ ํ์ธ (๋ก๊ทธ ๋ฉ์์ง)
Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
Airbag made by KENEL
Battery is ready
Car is ready
#4 ์ฝ๋ ์์ - @Named ์ฌ์ฉ
#4-1 @Provides์ ๋ฐํํ์ด ์ค๋ณต๋๋ค๋ฉด?

๋ง์ฝ, Battery๋ Airbag๊ณผ ๊ฐ์ ๋ฐ์ดํฐํ์ธ Dependency๋ฅผ ์๊ตฌํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
// package com.example.provides
import android.util.Log
import javax.inject.Inject
class Battery @Inject constructor(private val manufacturer: String) {
fun startBattery() {
Log.i("interfacer_han", "${this::class.simpleName} is ready")
Log.i("interfacer_han", "${this::class.simpleName} made by ${manufacturer}")
}
}
์ผ๋จ Battery ํด๋์ค๋ฅผ ์์ ๊ฐ์ด ์์ ํ๋ค.
// package com.example.provides
import dagger.Module
import dagger.Provides
@Module
class MyModule {
@Provides
fun providesAirbagManufacturer(): String {
return "KENEL"
}
@Provides
fun providesBatteryManufacturer(): String {
return "TISTORY"
}
}
๊ทธ๋ฆฌ๊ณ @Module ํด๋์ค๋ ์ด๋ ๊ฒ ์์ ํด๋ณธ๋ค.
#4-2 ํ๋ก์ ํธ ๋น๋ ์ ๋จ๋ ์๋ฌ ๋ฉ์์ง
error: [Dagger/DuplicateBindings] java.lang.String is bound multiple times
dagger ์
์ฅ์์, ์ด๋ค @Provides ํจ์๋ฅผ ์ฌ์ฉํด์ผํ๋ ์ง ๊ฒฐ์ ํ ์ ์๊ธฐ์ ๋จ๋ ์๋ฌ๋ค. dagger๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํจ์์ ๋ฐํํ์ ๊ธฐ์ค์ผ์ ์์์ ์์กด์ฑ ์ฃผ์
์ ์ํํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ๋ฐํํ์ด ์ค๋ณต๋๋ ํ ์์ ์์ , dagger๊ฐ ์์กด์ฑ ์ฃผ์
์ ์ํํ๋ ๋ฐ ์์ด ๋ ๋ค๋ฅธ ๊ธฐ์ค ์์๊ฐ ํ์ํ๋ค.
์ฌ๋ด์ผ๋ก, ํจ์ ์ด๋ฆ(์ฌ๊ธฐ์๋ providesAirbagManufacturer() ๋ฐ providesBatteryManufacturer())์ dagger ์
์ฅ๊ณผ ๋น์ฐํ ๊ด๋ จ์ด ์๋ค. ๋ฉ์๋ ์ด๋ฆ์ ํ๋๊ทธ๋๋จธ ์
์ฅ์์์ ๊ฐ๋
์ฑ๊ณผ ๊ด๋ จ๋ ์์์ผ ๋ฟ์ด๋ค.
#4-3 @Named ์ฌ์ฉ - @Module์์
...
import javax.inject.Named
@Module
class MyModule {
@Provides
@Named("Airbag")
fun providesAirbagManufacturer(): String {
return "KENEL"
}
@Provides
@Named("Battery")
fun providesBatteryManufacturer(): String {
return "TISTORY"
}
}
๊ทธ ๋ ๋ค๋ฅธ ์์๋ ๋ฐ๋ก @Named ์ด๋
ธํ
์ด์
์ด๋ค. @Named๋ ๋์ผํ ๋ฐ์ดํฐ ํ์
์ธ Dependency๊ฐ ์ฌ๋ฌ๊ฐ ์์ ๋ ๊ฐ๊ฐ์ Dependency๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด์ ์ฌ์ฉ๋๋ค.
#4-4 @Named ์ฌ์ฉ - @Inject์์
...
import javax.inject.Named
class Airbag @Inject constructor(@Named("Airbag") private val manufacturer: String) {
fun startAirbag() {
Log.i("interfacer_han", "${this::class.simpleName} is ready")
Log.i("interfacer_han", "${this::class.simpleName} made by ${manufacturer}")
}
}
@Inject๊ฐ ๋ถ์ ์์ฑ์์ ์ธ์์๋ #4-3์ ๋งค์นญ๋๋ @Named ์ด๋
ธํ
์ด์
์ ๋ถ์ฌ์ค๋ค.
#4-5 ์๋ ํ์ธ (๋ก๊ทธ ๋ฉ์์ง)
Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
Airbag made by KENEL
Battery is ready
Battery made by TISTORY
Car is ready
#5 ์์ฝ
@Inject๊ฐ ๋ถ๊ฐํ ํด๋์ค๋ @Provides๋ก ์ ๊ณต(Provide)ํ๊ณ , ์ ๊ณต๋๋ ๊ฒ๋ผ๋ฆฌ์ ๊ตฌ๋ถ์ @Named๋ก ํ๋ค.
#6 ์์ฑ๋ ์ฑ
android-practice/dagger2/Provides at master ยท Kanmanemone/android-practice
Contribute to Kanmanemone/android-practice development by creating an account on GitHub.
github.com
#7 ์ด์ด์ง๋ ๊ธ
[Android] Dagger2 - ๋งค๊ฐ๋ณ์
#1 ์ด์ ๊ธ [Android] Dagger2 - @Provides#1 ์ด์ ๊ธ [Android] Dagger2 - ๊ธฐ์ด#1 ์ด์ ๊ธ ์์กด์ฑ ์ฃผ์ (Dependency Injection)#1 ์์กด์ฑ ์ฃผ์ (Dependency Injection)์ด๋?#1-1 Dependent์ Dependencyfun main() { val car = Car() car.startCar
kenel.tistory.com
์ด์ด์ง๋ ๊ธ์์ @Provides ๋๋ @Module์ด ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง๊ฒ ๋ง๋ค์ด๋ณธ๋ค.
'๊นจ์ ๊ฐ๋ ๐ > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android] Dagger2 - ์ธํฐํ์ด์ค ๊ตฌํ์ฒด ์ฃผ์ (@Binds) (0) | 2024.06.25 |
---|---|
[Android] Dagger2 - ๋งค๊ฐ๋ณ์ ๋์ ํ ๋น (0) | 2024.06.24 |
[Android] Dagger2 - ๊ธฐ์ด (0) | 2024.06.24 |
[Android] WorkManager - ๋ณ๋ ฌ Chaining (0) | 2024.06.17 |
[Android] WorkManager - ์์ ์ฐ์ํ๊ธฐ(Chaining) (0) | 2024.06.17 |