12
15

๋ฉ€ํ‹ฐ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ข…์†์„ฑ ์‚ฝ์ž…(DI: Dependency Injection)์„ ํ•ด์ค˜์•ผํ•˜๋Š”๋ฐ ์ด๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ Hilt๋‹ค.

์ข…์†์„ฑ ์‚ฝ์ž…์€ ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ผ๊ณ ๋„ ํ•˜๋Š”๋ฐ ํŠน์ • ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋  ๋•Œ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ฆ‰ ๊ฐ์ฒด ๋ผ๋ฆฌ๋Š” ๊ฐ์ฒด ์ƒ์„ฑ๊ณผ ๋ฌด๊ด€ํ•˜๊ณ , ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„๊ณผ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๋ถ€๋ถ„์ด ๋ถ„๋ฆฌ๋œ ๊ฒƒ์ด๋ผ๊ณ  ์ดํ•ดํ–ˆ๋‹ค.

 

DI ๊ด€๋ จํ•ด์„œ Hilt๋Š” ์ด๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ๋ง๊ณ  ๋”ฐ๋กœ ๋‹ค๋ค„์„œ ๋” ๊นŠ๊ฒŒ ์—ฐ๊ตฌํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

Hilt ํƒ๊ตฌ

์›๋ž˜ ์‚ฌ์šฉ๋˜๋˜ Dagger๋ฅผ ํ™œ์šฉํ•ด ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  Android ๊ตฌ์„ฑ์š”์†Œ์— ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ œ๊ณตํ•˜๊ณ , ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ ์ˆ˜๋ช…์ฃผ๊ธฐ๋ฅผ Hilt๊ฐ€ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

Dagger๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋นŒ๋“œ๋œ Hilt๊ฐ€ ์ข‹์€ ์ ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค

  • ๊ฐ์ฒด์ƒ์„ฑ ๋ฐฉ๋ฒ•๊ณผ ์ฃผ์ž…์œ„์น˜๋งŒ ์ •์˜ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ ๊ฐ์†Œ
  • ๋นŒ๋“œ ์˜์กด์„ฑ ๋ถ„๋ฆฌ
  • ๋ฆฌํŒฉํ† ๋ง, ํ…Œ์ŠคํŠธ ํŽธ์˜์„ฑ
  • ์•ˆ๋“œ๋กœ์ด๋“œ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•จ์— ๋”ฐ๋ผ ํ‘œ์ค€ํ™” ๋œ ์ปดํฌ๋„ŒํŠธ

๋งˆ์ง€๋ง‰ ์ค„์€ Activity, Fragment์™€ ๊ฐ™์€ ์•ˆ๋“œ๋กœ์ด๋“œ ํด๋ž˜์Šค์— ์ž๋™์œผ๋กœ ๋งž๋Š” ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ค€๋‹ค๋Š” ์˜๋ฏธ๋‹ค. ์ด๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด @AndroidEntryPoint.

ํ”„๋กœ์ ํŠธ์— Hilt ์ถ”๊ฐ€

Project์ˆ˜์ค€ build.gradleํŒŒ์ผ์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. buildscript ์ฝ”๋“œ๋ธ”๋Ÿญ์€ ํ•ญ์ƒ plugins ๋ธ”๋Ÿญ ์œ„์— ์žˆ์–ด์•ผํ•œ๋‹ค. ์ฝ”๋“œ๋žฉ์—๋Š” 2.28-alpha๋ฒ„์ „์ธ๋ฐ ํ˜„์žฌ stable๋กœ 2.44๊นŒ์ง€ ๋‚˜์™”์œผ๋‹ˆ 2.44๋กœ ์ง€์ •ํ–ˆ๋‹ค.

buildscript {
    ext.hilt_version = '2.44'
    dependencies {

        classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
    }
}

app๋ชจ๋“ˆ์—์„œ gradle ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์“ฐ๊ธฐ์œ„ํ•ด์„œ kapt๋ฅผ app์ˆ˜์ค€ build.gradle์— ๋„ฃ์–ด์ค€๋‹ค.

id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'

๋™์ผ ํŒŒ์ผ ํ•˜๋‹จ์— dependencies์— ์ด๊ฒƒ๊นŒ์ง€ ์ถ”๊ฐ€ํ•œ ๋’ค syncํ•ด์ฃผ๋ฉด ์„ธํŒ… ๋์ด๋‹ค.

dependencies {
    //hilt
    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
}

์ด๊ฑธ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  sync ๋จผ์ €ํ•˜๋ฉด ๋‹น์—ฐํžˆ ๊ฐ€์ ธ์˜ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฃผ์†Œ๊ฐ€ ์—†์œผ๋‹ˆ hilt๊ฐ€ ์—†๋‹ค๊ณ  ๋‚˜์˜จ๋‹ค.(์‚ฝ์งˆ๊ฒฝํ—˜)

๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฒ•

์•ฑ์˜ ์ˆ˜๋ช…์ฃผ๊ธฐ์— ์—ฐ๊ฒฐ๋œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด @HiltAndroidApp์„ ๋‹ฌ๋ฉด ๋œ๋‹ค.

@HiltAndroidApp
class SuChelinApp: Application() {

}

์ด ์ปจํ…Œ์ด๋„ˆ๋Š” ์ตœ์ƒ์œ„ ์ปจํ…Œ์ด๋„ˆ์ด๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ ์ œ๊ณตํ•˜๋Š” ์ข…์†ํ•ญ๋ชฉ์— ๋‹ค๋ฅธ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ๋Š” ์ข…์†ํ•ญ๋ชฉ์„ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ˆ˜๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋„๊ตฌ๋‹ค.

Fragment๋‚˜ Activity์—์„œ Hilt๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด @AndroidEntryPoint๋กœ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋‹ฌ๋ฉด ๋œ๋‹ค.

@AndroidEntryPoint
class LogsFragment : Fragment() {

}

์ด๋Ÿฌ๋ฉด Activity, Fragment์˜ ์ˆ˜๋ช…์ฃผ๊ธฐ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋Š” ์ข…์†ํ•ญ๋ชฉ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. ๋˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š”๋ฐ, ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

@AndroidEntryPoint
class LogsFragment : Fragment() {
    @Inject lateinit var logger: LoggerLocalDataSource
    @Inject lateinit var dateFormatter: DateFormatter
}

์™ธ๋ถ€์—์„œ ์ƒ์„ฑํ•ด๋‘” ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์ฝ”๋“œ๋‹ค.

class LoggerLocalDataSource @Inject constructor(private val logDao: LogDao) {
    ...
}

์ด๋Ÿฐ์‹์œผ๋กœ ํ•˜๋ฉด ํŠน์ • ํด๋ž˜์Šค์— ์ข…์†๋˜์ง€์•Š์€ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ฃผ์ž…๋œ๋‹ค.

์ธ์Šคํ„ด์Šค ๋ฒ”์œ„๋Š” @Singleton์„ ๋ถ™์—ฌ์„œ ์ „์—ญ์œผ๋กœ ๋งŒ๋“ค์–ด ํ•ญ์ƒ ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜, ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๋งŒ๋“ค์ง€์•Š๊ณ  ํ•ญ์ƒ ๋‹ค๋ฅด๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

@Singleton
class LoggerLocalDataSource @Inject constructor(private val logDao: LogDao) {
    ...
}

Hilt ๋ชจ๋“ˆ

์ƒ์„ฑ์ž๊ฐ€ ์‚ฝ์ž…๋  ์ˆ˜ ์—†๋Š” ์œ ํ˜•(์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ฐ™์€)์€ Hilt ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

๋ชจ๋“ˆ์€ @Module๊ณผ @InstallIn ์–ด๋…ธํ…Œ์ด์…˜์„ ๋‹ฌ์•„๋‘” ํด๋ž˜์Šค๋‹ค. @Module์€ ๋ง ๊ทธ๋Œ€๋กœ ๋ชจ๋“ˆ์ž„์„ Hilt์— ์•Œ๋ฆฌ๋Š” ์—ญํ• ์ด๊ณ  @InstallIn์€ ์–ด๋–ค ์ปจํ…Œ์ด๋„ˆ์—์„œ Hilt์š”์†Œ๋ฅผ ์ง€์ •ํ•ด ๊ฒฐํ•ฉ์„ ์‚ฌ์šฉํ• ์ง€๋ฅผ Hilt์— ์•Œ๋ฆฐ๋‹ค.

์ง€์ •ํ• ์ˆ˜์žˆ๋Š” Hilt ๊ตฌ์„ฑ์š”์†Œ๋Š” ์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด๋œ๋‹ค.

์ด๊ฒŒ Hilt ๊ตฌ์„ฑ์š”์†Œ ๊ณ„์ธต ๊ตฌ์กฐ๋‹ค. ์ƒ์œ„ ์š”์†Œ์— ํ•˜์œ„์š”์†Œ๊ฐ€ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    const val BASEURL = ""

}

์ด ์ฝ”๋“œ๋Š” SingletonComponent๋ฅผ ์ง€์ •ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋‹ค. ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์€ ์–ด์ฐจํ”ผ ๊ณ„์† ํ•  ๊ฒƒ์ด๋ฏ€๋กœ ๋งค๋ฒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๋งŒ๋“ค์–ด์„œ ์ ‘๊ทผ์ด ์‰ฝ๊ฒŒ ํ•˜๋Š”๊ฒŒ ๋‚ซ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ชจ๋“ˆ ์•ˆ์˜ ํ•จ์ˆ˜์— @Provides๋ฅผ ๋‹ฌ๋ฉด ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์‹œ ํ•„์š”ํ•œ ๊ฒƒ์„ Hilt์— ์•Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

@Module
object DatabaseModule {

    @Provides
    fun provideLogDao(database: AppDatabase): LogDao {
        return database.logDao()
    }
}

Hilt์—๊ฒŒ provideLogDao๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ LogDao ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ database.logDao()๋ฅผ ์‹คํ–‰ํ•ด์•ผ๋œ๋‹ค๊ณ  ์•Œ๋ฆฌ๋Š” ์ฝ”๋“œ๋‹ค.

์ถ”์ƒํด๋ž˜์Šค์˜ ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์„œ๋“œ๋Š” @Binds ๋ฅผ ๋ถ™์—ฌ ์‚ฌ์šฉํ•˜๋ฉด๋œ๋‹ค

@InstallIn(ActivityComponent::class)
@Module
abstract class NavigationModule {

    @Binds
    abstract fun bindNavigator(impl: AppNavigatorImpl): AppNavigator
}

์ฐธ์กฐ:

https://developer.android.com/codelabs/android-hilt?hl=ko&authuser=1#0

https://developer.android.com/training/dependency-injection?authuser=1&hl=ko#choosing-right-di-tool

https://developer.android.com/training/dependency-injection/hilt-android?authuser=1&hl=ko#component-default

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

๋ฐ˜์‘ํ˜•
COMMENT