header-img
Info :

Dependency

ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค์— ์˜์กดํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ. A ํด๋ž˜์Šค๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด B ํด๋ž˜์Šค๋ฅผ ํ•„์š”๋กœ ํ•  ๋•Œ B๋Š” A์˜ ์˜์กด ๋Œ€์ƒ์ด ๋จ. ์˜ˆ๋ฅผ ๋“ค์–ด ์ƒ๋Ÿฌ๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋“œ๋ ˆ์‹ฑ์ด ํ•„์š”ํ•จ. ์ƒ๋Ÿฌ๋“œ๋Š” ๋“œ๋ ˆ์‹ฑ์— ์˜์กดํ•˜๊ณ  ์žˆ์Œ. ๋”ฐ๋ผ์„œ ์ƒ๋Ÿฌ๋“œ ← ๋“œ๋ ˆ์‹ฑ ๊ด€๊ณ„๊ฐ€ ๋จ. ์—ฌ๊ธฐ์„œ ๋“œ๋ ˆ์‹ฑ์ด ์˜์กด์˜ ๋Œ€์ƒ, Dependency๊ฐ€ ๋จ.

 

Injection

์œ„์˜ ์˜ˆ๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•ด์„œ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ƒ๋Ÿฌ๋“œ ํด๋ž˜์Šค, ๋“œ๋ ˆ์‹ฑ ํด๋ž˜์Šค๊ฐ€ ์žˆ์„ ๋•Œ ์ƒ๋Ÿฌ๋“œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋“œ๋ ˆ์‹ฑ์˜ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•จ. ํ•˜์ง€๋งŒ ์ด ๋“œ๋ ˆ์‹ฑ ๊ฐ์ฒด๋ฅผ ์ƒ๋Ÿฌ๋“œ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์™ธ๋ถ€์—์„œ ๋งŒ๋“ค์–ด์„œ ๊ฑด๋„ค์ฃผ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Œ. ์ด๋ ‡๊ฒŒ ์™ธ๋ถ€์—์„œ ์˜์กด๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ๋Œ€์ƒ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ์˜์กด์„ฑ(Dependency)์„ ์™ธ๋ถ€์—์„œ ์ฃผ์ž…(Inject)ํ•ด์ค€๋‹ค๊ณ  ํ•จ. ๋”ฐ๋ผ์„œ ๋“œ๋ ˆ์‹ฑ์˜ ์ข…๋ฅ˜๊ฐ€ ๋ฐœ์‚ฌ๋ฏน ๋“œ๋ ˆ์‹ฑ์ด์—ˆ๋Š”๋ฐ ์š”๊ฑฐํŠธ ๋“œ๋ ˆ์‹ฑ์œผ๋กœ ๋ฐ”๋€๋‹ค๊ณ  ์ƒ๋Ÿฌ๋“œ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š” ์—†์ด ์ฃผ์ž…๋งŒ ๋ฐ›์œผ๋ฉด ๋จ. → Test์— ํŽธํ•ด์ง€๊ธฐ๋„ ํ•จ.

 

DI : Dependency Injection

์ค‘์š”ํ•œ ์š”์ง€๋Š” ์˜์กด์„ฑ์ด ์žˆ๋Š” ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์˜์กด์˜ ๋Œ€์ƒ์ด ๋˜๋Š” ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์™ธ๋ถ€์—์„œ ๋„˜๊ฒจ๋ฐ›์•„์•ผ ํ•จ. ๊ทธ๋ ‡๋‹ค๋ฉด ๊ทธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” constructor์—์„œ ๋„˜๊ฒจ์ฃผ๊ฑฐ๋‚˜, setter ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐฉ์‹์ด ์žˆ์Œ. ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ DI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ๋Š” Koin, Dagger, Hilt๊ฐ€ ์žˆ์Œ. ์ด์ค‘ Hilt๊ฐ€ ํ•™์Šต ๊ณก์„ ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋‚ฎ์€ ํŽธ์ด๋ผ๊ณ  ํ•ด์„œ Hilt์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•  ์˜ˆ์ •์ž„.

์˜์กด์„ฑ ์ฃผ์ž…์„ ํ–ˆ์„ ๋•Œ ์žฅ์ ์œผ๋กœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ.

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

 

Hilt

๊ตฌ๊ธ€์˜ Dagger๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“  DI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.

Hilt๋Š” Android ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์กฐ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ณ , ์œ ์ง€ ๊ด€๋ฆฌ ๋ฐ ํ™•์žฅ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๋ฉฐ, ์ข…์†์„ฑ ์ฃผ์ž… ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

 

์‹œ์ž‘ํ•˜๊ธฐ

build.gradle์— ์ข…์†์„ฑ ์ถ”๊ฐ€

 

@HiltAndroidApp

Hilt ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์•ฑ์€ @HiltAndroidApp Annotation์œผ๋กœ ์ง€์ •๋œ Application Class๋ฅผ ํฌํ•จํ•ด์•ผ๋งŒ ํ•จ. @HiltAndroidApp์€ Hilt์˜ ์ฝ”๋“œ ์ƒ์„ฑ์„ ํŠธ๋ฆฌ๊ฑฐํ•จ. annotation์œผ๋กœ ์ƒ์„ฑ๋œ Hilt ๊ตฌ์„ฑ์š”์†Œ๋Š” Application ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์ฃผ๊ธฐ์— ์—ฐ๊ฒฐ๋จ. ApplicationContext์— Hilt๊ฐ€ ์ ‘๊ทผํ•  ์ผ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ณผ์ •์ด ํ•„์š”ํ•จ. Application Class๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋‹ค๊ฐ€ ์ถ”๊ฐ€ํ–ˆ๋‹ค๋ฉด AndroidManifest.xml์— application ํƒœ๊ทธ์— ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•จ.

@HiltAndroidApp
class MainApplication : Application() {
}

 

Hilt๊ฐ€ ์ง€์›ํ•˜๋Š” Android Class

  • Application (@HiltAndroidApp ์‚ฌ์šฉ)
  • ViewModel (@HiltViewModel ์‚ฌ์šฉ)
  • Activity (@AndroidEntrypoint ์‚ฌ์šฉ)
  • Fragment (@AndroidEntrypoint ์‚ฌ์šฉ)
  • View (@AndroidEntrypoint ์‚ฌ์šฉ)
  • Service (@AndroidEntrypoint ์‚ฌ์šฉ)
  • BroadcastReceiver (@AndroidEntrypoint ์‚ฌ์šฉ)

 

Hilt๊ฐ€ ์ƒ์„ฑํ•˜๋Š” Component์˜ ๊ณ„์ธต ๊ตฌ์กฐ

 

์ตœ์ƒ์œ„๋Š” ApplicationClass๋ฅผ ์‚ฌ์šฉํ•˜๋Š” SingletonComponent๊ฐ€ ๋จ. ๊ฐ Component๋“ค์€ ๊ทธ ๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ Dependency๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ.

 

@AndroidEntryPoint

์•ˆ๋“œ๋กœ์ด๋“œ ํด๋ž˜์Šค์— @AndroidEntryPoint Annotation์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ํด๋ž˜์Šค์— ์ข…์†๋œ ๋‹ค๋ฅธ ํด๋ž˜์Šค์—๋„ ํ•ด๋‹น Annotation์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ. @AndroidEntryPoint๋Š” ํ”„๋กœ์ ํŠธ์˜ ๊ฐ Android ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๊ฐœ๋ณ„ Hilt ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•จ

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    }
}

 

@Inject

@Inject ์ฃผ์„์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•„๋“œ ์‚ฝ์ž…์„ ํ•จ. Hilt๊ฐ€ ์‚ฝ์ž…ํ•œ ํ•„๋“œ๋Š” private์ด ๋ถˆ๊ฐ€๋Šฅํ•จ. @Inject๋ฅผ ์‚ฌ์šฉํ•ด์„œ Constructor Injection๋„ ๊ฐ€๋Šฅํ•จ.

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {

  @Inject lateinit var analytics: AnalyticsAdapter
  ...
}

 

Hilt @Inject ๋” ์ž์„ธํ•˜๊ฒŒ - 1

ํ•„๋“œ์— ์™ธ๋ถ€ ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•ด์ฃผ๋ ค๋ฉด Hilt๊ฐ€ ์–ด๋–ป๊ฒŒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š”์ง€ ์•Œ์•„์•ผ ํ•จ. binding์—๋Š” ํŠน์ • ์œ ํ˜•์˜ ์ธ์Šคํ„ด์Šค๋ฅผ dependency๋กœ ์ œ๊ณตํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ info๊ฐ€ ๋“ค์–ด์žˆ์Œ. ํด๋ž˜์Šค์˜ constructor์— @Inject ์ฃผ์„์„ ์‚ฌ์šฉํ•ด์„œ Hilt์— ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•จ.

class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

@Inject ์ฃผ์„์ด ์ง€์ •๋œ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ทธ ํด๋ž˜์Šค์˜ ์ข…์† ํ•ญ๋ชฉ์ž„. ์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” AnalyticsAdapter ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์— @Inject annotation์ด ์žˆ๊ณ  ์ด ์ƒ์„ฑ์ž๋Š” AnalyticsService๊ฐ€ ์ข…์† ํ•ญ๋ชฉ์œผ๋กœ ์žˆ์Œ. ๊ทธ๋ž˜์„œ Hilt์—๊ฒŒ AnalyticsAdapter ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ AnalyticsService ๊ฐ์ฒด๋„ ์ƒ์„ฑํ•˜์—ฌ ์ฃผ์ž…ํ•ด์ฃผ์–ด์•ผ ํ•จ์„ ์•Œ๋ ค์คŒ. ์œ„์™€ ๊ฐ™์ด Constructor Injection์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ์Œ. Constructor Injection์€ ์ƒ์„ฑ ์‹œ ์–ด๋–ค ํด๋ž˜์Šค์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•„์š”ํ•œ์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Œ. → ๊ฐ€๋…์„ฑ์— ์ข‹์Œ.

๋˜ํ•œ ์œ„์˜ AnalyticsAdapter ํด๋ž˜์Šค๋Š” Component๋“ค์—์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•จ. ์˜ˆ์‹œ๋กœ๋Š” @AndroidEntryPoint annotation์„ ๋ถ™์ธ Activity์—์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•จ. ์•„๋ž˜ ์ฝ”๋“œ๋Š” Constructor Injection์ด ์•„๋‹Œ Field Injection์„ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•์ž„. ๋‹ค์‹œ ํ•œ ๋ฒˆ Field Injection์€ ์ ‘๊ทผ ์ œํ•œ์ž๋ฅผ private์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ์•ˆ ๋จ!

@AndroidEntryPoint
class ActivitySample : AppCompatActivity() {
		@Inject
		lateinit var analyticsAdapter: AnalyticsAdapter
		
		...
}

โ“ ๋‚ด๊ฐ€ ํ—ท๊ฐˆ๋ฆฐ ๋ถ€๋ถ„ : @Inject Annotation์€ ๊ทธ๋Ÿผ ์ฃผ์ž…์„ ๋ฐ›์„ ๋Œ€์ƒ์— ๋ถ™์ด๋Š”๊ฒŒ ๋งž๋‚˜? → No ๐Ÿ™…‍โ™€๏ธ

@Inject ์–ด๋…ธํ…Œ์ด์…˜์€ ์ฃผ์ž…์„ ๋ฐ›์„ ๋Œ€์ƒ๊ณผ ์ฃผ์ž…์„ ์ œ๊ณตํ•˜๋Š” ๋Œ€์ƒ ๋ชจ๋‘์—๊ฒŒ ๋ถ™์—ฌ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋ณดํ†ต ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์—์„œ ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›์„ ๋•Œ @Inject ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜์— @Inject ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ๊ฒฝ์šฐ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋„๋ก Dagger๋‚˜ Hilt์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ž๋™์œผ๋กœ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ, ์ฃผ์ž…์„ ๋ฐ›์„ ๋Œ€์ƒ์˜ ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜์— @Inject ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ์ค˜์•ผ ํ•˜๊ณ , ์˜์กด์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ๋Œ€์ƒ(์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค๋ฅธ ํด๋ž˜์Šค๋‚˜ ๋ชจ๋“ˆ)์˜ ๋ฉ”์„œ๋“œ ๋˜๋Š” ํ•„๋“œ์—๋„ @Inject ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ๋Œ€์ƒ์„ ์•Œ์•„๋‚ด๊ณ , ์ž๋™์œผ๋กœ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ @Inject๋Š” Dependency Graph๋ฅผ ์ด์–ด์ค€๋‹ค๊ณ  ํ•จ. Hilt๊ฐ€ inject annotation์ด ๋ถ™์–ด์žˆ๋Š” :: Dependency๋ฅผ ์ฃผ์ž… ๋ฐ›์„ ๊ฐ์ฒด์™€ Dependency๋ฅผ ์ œ๊ณตํ•ด์„œ ์ƒ์„ฑํ•  ๊ฐ์ฒด์˜ ํด๋ž˜์Šค์— Dependency Graph๋ฅผ ์ด์–ด๋ถ™์—ฌ์คŒ.

 

Hilt ๋ชจ๋“ˆ

constructor๋กœ ์ฃผ์ž…์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ Hilt ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•ด์„œ Hilt์— binding info๋ฅผ ์ œ๊ณตํ•จ. constructor๋กœ ์ฃผ์ž…์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ.

  • ์ธํ„ฐํŽ˜์ด์Šค
    • A interface๋ฅผ B Class, C Class์—์„œ implementํ•ด์„œ ๊ตฌํ˜„ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ ๊ฐ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์— A interface๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ์•ˆ๋จ. ์—๋Ÿฌ ๋ฐœ์ƒ.
  • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํด๋ž˜์Šค

๋”ฐ๋ผ์„œ ์œ„์™€ ๊ฐ™์€ ๊ฒฝ์šฐ Hilt ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ. Hilt ๋ชจ๋“ˆ์€ @Module๋กœ Annotation์ด ์ง€์ •๋œ ํด๋ž˜์Šค์ž„. ๋˜ํ•œ @InstallIn ์ฃผ์„์„ ์ง€์ •ํ•˜์—ฌ ๊ฐ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์•ˆ๋“œ๋กœ์ด๋“œ ํด๋ž˜์Šค๋ฅผ Hilt์— ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•จ. Hilt ๋ชจ๋“ˆ์— ์ œ๊ณตํ•œ dependency๋“ค์€ Hilt ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•œ Android Class์˜ ๋ชจ๋“  ๊ตฌ์„ฑ์š”์†Œ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ. ์ฆ‰ @Module annotation์€ Hilt์—๊ฒŒ ์ด ํด๋ž˜์Šค๊ฐ€ Module์ด ์žˆ๋Š” ๊ณณ์ด๋ผ๊ณ  ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๊ณ  @InstallIn annotation์€ ํ•ด๋‹น ๋ชจ๋“ˆ์ด activity์™€ ๊ฐ™์€ Hilt ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•œ ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์„ ์–ธํ•˜๋Š” ์˜๋ฏธ์ž„.

Module์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ๋Š” Provides Annotation๊ณผ Binds Annotation์ด ์žˆ์Œ. Provides ๋ฐฉ์‹์ด ๋” ํŽธํ•˜๋‹ค๊ณ  ํ•˜๊ณ  ์ž„์˜์˜ module class๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์—ฌ๊ธฐ์— ํด๋ž˜์Šค๋“ค ์ž‘์„ฑํ•˜๋Š” ์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•จ.

 

@Provides

์ผ๋‹จ Porvides Annotation ๋ฐฉ์‹์œผ๋กœ Module์„ ์ƒ์„ฑํ•œ๋‹ค๊ณ  ํ•ด๋„ @Module, @InstallIn annotation์„ ๋ถ™์—ฌ์ฃผ์–ด์•ผ ํ•จ. ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“ˆ ํด๋ž˜์Šค ๋‚ด๋ถ€์— @Provides annotation์„ ์‚ฌ์šฉํ•ด์„œ Provides ํ•จ์ˆ˜๋“ค์„ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•จ.

https://developer88.tistory.com/349 ์ด ๋ธ”๋กœ๊ทธ๋ฅผ ๋ณด๊ณ  ๋”ฐ๋ผํ•œ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ.

์ฒซ ๋ฒˆ์งธ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์„ค๋ช… : ClassBForInterfaceTest ํด๋ž˜์Šค๋Š” InterfaceA๋ฅผ Implementsํ•œ ํด๋ž˜์Šค์ด๊ณ  ๋”ฐ๋ผ์„œ showString() method๋ฅผ overrideํ•จ. ์ด ๋ฉ”์†Œ๋“œ์—์„œ๋Š” stringDependency๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ํฌํ•จํ•˜๋Š” ์ŠคํŠธ๋ง์„ ๋ฆฌํ„ดํ•˜๋Š”๋ฐ ์ด stringDependency ๋ณ€์ˆ˜๋Š” ClassBForInterfaceTest ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ์‹œ ์ฃผ์ž…๋˜๋„๋ก ์ƒ์„ฑ์ž์—์„œ @Inject ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์„ ์–ธํ•ด๋†“์•˜์Œ. ๊ทธ๋ฆฌ๊ณ  ClassAForInterfaceTest ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ ์‹œ InterfaceA๋ฅผ ์ฃผ์ž…๋ฐ›๋„๋ก ํด๋ž˜์Šค ์ƒ์„ฑ์ž์— @Inject ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์„ ์–ธํ•ด๋†“์Œ.

๋‘ ๋ฒˆ์งธ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์„ค๋ช… : ClassBForInterfaceTest๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฃผ์ž…๋ฐ›์•„์•ผ ํ•จ. ๋”ฐ๋ผ์„œ Module์„ ์ƒ์„ฑํ•ด์ฃผ์–ด์•ผ ํ•˜๋ฏ€๋กœ @Module, @InstallIn annotation์„ ์‚ฌ์šฉํ•จ. @InstallIn annotation์„ ์‚ฌ์šฉํ•ด ์ด ๋ชจ๋“ˆ์ด ์‚ฌ์šฉ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ActivityComponent๋กœ ์ง€์ •ํ•ด์คฌ์Œ. → ์ด ๋ง์€ ์ฆ‰ Activity์—์„œ ์ด ์˜์กด์„ฑ์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ž„. ๋”ฐ๋ผ์„œ Activity class์—์„œ @Inject๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ค„ ์ˆ˜ ์žˆ๊ฒŒ ๋จ.

interface InterfaceA {
    fun showString(): String
}

class ClassAForInterfaceTest @Inject constructor(private val bClass: InterfaceA) {
    fun doTestA(): String {
        return bClass.showString()
    }
}

class ClassBForInterfaceTest
@Inject constructor(private val stringDependency: String) : InterfaceA {
    override fun showString(): String {
        return "stringDependency : ${stringDependency}"
    }
}
@Module
@InstallIn(ActivityComponent::class)
class ModuleForInterface {
    @Provides
    fun provideString(): String {
        return "dependency String by ModuleForInterface"
    }

    @Provides
    fun testProvides(cString: String): InterfaceA {
        return ClassBForInterfaceTest(cString)
    }
}
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var classAForInterfaceTest : ClassAForInterfaceTest

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = classAForInterfaceTest.doTestA()
        println(text)
    }
}

โ“๊ถ๊ธˆํ•ด์„œ ํ•ด๋ณธ ๊ฒƒ : @Module์—์„œ string ํƒ€์ž…์„ ์ฃผ์ž…ํ•ด์ฃผ๊ณ  ์žˆ๋Š”๋ฐ String์„ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ๋ผ๋ฉด..? → ๋ญ˜ provide ํ•ด์ค„์ง€ ๋ชจ๋ฅด๋ฏ€๋กœ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

@Module
@InstallIn(ActivityComponent::class)
class ModuleForInterface {
    @Provides
    fun provideString(): String {
        return "dependency String by ModuleForInterface"
    }

    @Provides
    fun provideString2(): String {
        return "dependency String 2 by ModuleForInterface"
    }

    @Provides
    fun testProvides(cString: String): InterfaceA {
        return ClassBForInterfaceTest(cString)
    }
}

โ“๊ถ๊ธˆํ•ด์„œ ํ•ด๋ณธ ๊ฒƒ 2 : @Module์—์„œ string ํƒ€์ž…์„ ์ฃผ์ž…ํ•ด์ฃผ๊ณ  ์žˆ๋Š”๋ฐ String์„ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ธ๋งŒํผ ๋ฐ›๋Š” ๊ฒƒ๋„ ์žˆ๋‹ค๋ฉด..? → ๋™์ผํ•˜๊ฒŒ ๋ญ˜ provide ํ•ด์ค„์ง€ ๋ชจ๋ฅด๋ฏ€๋กœ ์˜ค๋ฅ˜ ๋ฐœ์ƒ. ํ•˜์ง€๋งŒ ํƒ€์ž…์ด ๋‹ค๋ฅธ ๊ฒƒ์€ ok์—ฌ์š”! (์•„๋ž˜ ์ฝ”๋“œ์—์„œ Int๋Š” Ok)

@Module
@InstallIn(ActivityComponent::class)
class ModuleForInterface {
    @Provides
    fun provideString(): String {
        return "dependency String by ModuleForInterface"
    }

    @Provides
    fun provideString2(): String {
        return "dependency String 2 by ModuleForInterface"
    }

    @Provides
    fun provideInt(): Int {
        return 1
    }

    @Provides
    fun testProvides(cString: String, cString2: String, num: Int): InterfaceA {
        Log.d("num", "$num")
        Log.d("string", "$cString2")
        return ClassBForInterfaceTest(cString)
    }
}

ํ•˜์ง€๋งŒ ์œ„์— ๊ถ๊ธˆํ•ด์„œ ํ•ด๋ดค๋‹ค๊ณ  ํ•œ ๊ฑด ์—ญ์‹œ ๋ฐฉ๋ฒ•์ด ์žˆ์—ˆ์Œ. ๋ฐ”๋กœ @Qualifier, @Retention annotation์„ ์‚ฌ์šฉํ•˜๋ฉด ๋จ. ์ด ๋ฐฉ๋ฒ•์„ ํ•œ์ •์ž ์ฃผ์ž…์ด๋ผ๊ณ  ํ•œ๋‹ค๊ณ  ํ•จ.

 

@Qualifier, @Retention

AI๊ฐ€ ์„ค๋ช…ํ•ด์ค€ ์ฝ”๋“œ
์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” QualifierTest ๋ชจ๋“ˆ์ด SingletonComponent์— @InstallIn ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— QualifierInterfaceType1๊ณผ QualifierInterfaceType2 ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ง„ Provides ๋ฉ”์„œ๋“œ๊ฐ€ Singleton ๋ฒ”์œ„ ๋‚ด์—์„œ ์œ ์ผํ•˜๊ฒŒ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•œ์ •์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜์กด์„ฑ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐฉ์‹์„ "ํ•œ์ •์ž ์ฃผ์ž…"์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ, QualifierTestClassA ์ƒ์„ฑ์ž์—์„œ QualifierInterfaceType1๊ณผ QualifierInterfaceType2 ํ•œ์ •์ž๋ฅผ ์ด์šฉํ•ด ๊ฐ๊ฐ์˜ ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด, QualifierTestClassA์—์„œ concatString() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด QualifierTestClassB์™€ QualifierTestClassC๊ฐ€ ๊ตฌํ˜„ํ•œ showString() ๋ฉ”์„œ๋“œ์˜ ๊ฒฐ๊ณผ๋ฅผ ํ•ฉ์นœ ๋ฌธ์ž์—ด์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

// Module

@Module
@InstallIn(SingletonComponent::class)
class QualifierTest {

    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    annotation class QualifierInterfaceType1

    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    annotation class QualifierInterfaceType2

    @QualifierInterfaceType1
    @Provides
    fun testProvides1(): QualifierInterface {
        return QualifierTestClassB()
    }

    @QualifierInterfaceType2
    @Provides
    fun testProvides2(): QualifierInterface {
        return QualifierTestClassC()
    }
}
// Class 

class QualifierTestClassA @Inject constructor(
    @QualifierTest.QualifierInterfaceType1 private val qInterfaceType1: QualifierInterface,
    @QualifierTest.QualifierInterfaceType2 private val qInterfaceType2: QualifierInterface
){
    fun concatString(): String{
        return qInterfaceType1.showString() + qInterfaceType2.showString()

    }
}

class QualifierTestClassB @Inject constructor(): QualifierInterface {
    override fun showString(): String {
        return "QualifierTestClassB"
    }
}

class QualifierTestClassC @Inject constructor(): QualifierInterface {
    override fun showString(): String {
        return "QualifierTestClassC"
    }

}

interface QualifierInterface {
    fun showString(): String
}
// Activity

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var qualifierTestClassA: QualifierTestClassA

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // qualifier test
        val text = qualifierTestClassA.concatString()
        println(text)
    }
}

 

@Binds

@Binds ์ฃผ์„์€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•ด์•ผํ•  ๋•Œ ์‚ฌ์šฉํ•  ๊ตฌํ˜„์„ Hilt์— ์•Œ๋ ค์คŒ. ๊ทธ๋Ÿฌ๋‚˜ @Binds ๋ฐฉ์‹์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ.

class BindTestClassA @Inject constructor(
    private val bindTestClassB: BindInterface
){
    fun testBindTestClassA(): String {
        return bindTestClassB.showString()
    }
}

class BindTestClassB @Inject constructor(): BindInterface{
    override fun showString(): String {
        return "BindTestClassB"
    }
}

interface BindInterface {
    fun showString(): String
}
@Module
@InstallIn(ActivityComponent::class)
abstract class ModuleForBind {
    @ActivityScoped
    @Binds
    abstract fun bindInterfaceDependency(bindTestClassB: BindTestClassB): BindInterface
}
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var bindTestClassA: BindTestClassA

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = bindTestClassA.testBindTestClassA()
        println(text)
    }
}

AI๊ฐ€ ์„ค๋ช…ํ•ด์ค€ @Module ๋ถ€๋ถ„ ์ฝ”๋“œ
@Module ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋Š” Hilt์—์„œ ์˜์กด์„ฑ ์ฃผ์ž…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ํ•„์š”ํ•œ ๋ฐ”์ธ๋”ฉ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”์ธ๋”ฉ ์ •๋ณด๋ž€ ์–ด๋–ค ํด๋ž˜์Šค๋ฅผ ์–ด๋–ค ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ์ถ”์ƒ ํด๋ž˜์Šค์— ๋ฐ”์ธ๋”ฉํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ •์˜ํ•œ ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
@Module ์–ด๋…ธํ…Œ์ด์…˜์—๋Š” @InstallIn ์–ด๋…ธํ…Œ์ด์…˜์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ชจ๋“ˆ์ด ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ์— ์„ค์น˜๋˜์–ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ์˜ˆ์‹œ์—์„œ๋Š” ActivityComponent์— ์„ค์น˜๋ฉ๋‹ˆ๋‹ค.
@Module ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค ๋‚ด๋ถ€์—๋Š” @Provides, @Binds, @Multibinds ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ”์ธ๋”ฉ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์ค‘์—์„œ @Binds ์–ด๋…ธํ…Œ์ด์…˜์€ ์ถ”์ƒ ํด๋ž˜์Šค๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
@Module ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค์ธ ModuleForBind ๋‚ด๋ถ€์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@Binds
abstract fun bindInterfaceDependency(bindTestClassB: BindTestClassB): BindInterface

์ด ์ฝ”๋“œ๋Š” BindTestClassB ํด๋ž˜์Šค๊ฐ€ ๊ตฌํ˜„ํ•˜๋Š” BindInterface ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ฆ‰, BindTestClassB ๊ฐ์ฒด๊ฐ€ BindInterface ํƒ€์ž…์œผ๋กœ ์ฃผ์ž…๋  ์ˆ˜ ์žˆ๋„๋ก Hilt์—๊ฒŒ ๋ฐ”์ธ๋”ฉ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด์ œ MainActivity์—์„œ BindTestClassA๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•  ๋•Œ, Hilt๋Š” BindTestClassB ๊ฐ์ฒด๋ฅผ BindInterface ํƒ€์ž…์œผ๋กœ ์ฃผ์ž…ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด BindTestClassA์—์„œ๋Š” BindInterface์— ์ •์˜๋œ showString() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ViewModel

@HiltViewModel์„ ์‚ฌ์šฉํ•˜๋ฉด ๋จ. ์ดํ›„ @AndroidEntryPoint ์ฃผ์„์œผ๋กœ ์ง€์ •๋œ ์•กํ‹ฐ๋น„ํ‹ฐ๋‚˜ ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ ****by viewModels() ํ‚ค์›Œ๋“œ๋กœ ๋ทฐ๋ชจ๋ธ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ.

@HiltViewModel
class MainViewModel @Inject constructor(
    @ModuleForViewModel.ViewModelIntType1 private val a: Int,
    @ModuleForViewModel.ViewModelIntType2 private val b: Int
): ViewModel() {

    fun getNum(): Int {
        return a + b
    }
}
@Module
@InstallIn(ViewModelComponent::class)
class ModuleForViewModel {

    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    annotation class ViewModelIntType1

    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    annotation class ViewModelIntType2

    @ViewModelIntType1
    @Provides
    fun provideA(): Int = 1

    @ViewModelIntType2
    @Provides
    fun provideB(): Int = 3
}
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private val mainViewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = mainViewModel.getNum().toShort()
        println(text)
    }
}

AI๊ฐ€ ์„ค๋ช…ํ•ด์ค€ ์ฝ”๋“œ
์ด ์ฝ”๋“œ๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ์˜ Hilt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋œ ๋ทฐ ๋ชจ๋ธ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.
์šฐ์„  @HiltViewModel ์–ด๋…ธํ…Œ์ด์…˜์€ ViewModel์— ๋Œ€ํ•œ ์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•œ Hilt-specific ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค.
MainViewModel ํด๋ž˜์Šค๋Š” @HiltViewModel ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ทฐ ๋ชจ๋ธ์ž„์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ๋‘ ๊ฐœ์˜ ์ •์ˆ˜ a์™€ b๋ฅผ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. a์™€ b๋Š” ModuleForViewModel ๋ชจ๋“ˆ์˜ ๋‘ ๊ฐœ์˜ ์–ด๋…ธํ…Œ์ด์…˜์— ์˜ํ•ด ์ œ๊ณต๋˜๋Š” @Provides ๋ฉ”์„œ๋“œ๋กœ ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค.
@ModuleForViewModel ๋ชจ๋“ˆ์—๋Š” ๋ทฐ ๋ชจ๋ธ์—์„œ ํ•„์š”ํ•œ a์™€ b ๊ฐ’์— ๋Œ€ํ•œ ์ œ๊ณต์ž๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ ViewModelComponent ์Šค์ฝ”ํ”„์— ์„ค์น˜๋˜์–ด ์žˆ์œผ๋ฉฐ ViewModel์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
๋งˆ์ง€๋ง‰์œผ๋กœ MainActivity ํด๋ž˜์Šค๋Š” Hilt๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ MainViewModel ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ MainViewModel ๊ฐ์ฒด์˜ getNum() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ a์™€ b๋ฅผ ๋”ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

 

๋ฏธํ•ด๊ฒฐ ์˜๋ฌธ

โ“hilt๋ฅผ ์‚ฌ์šฉํ•ด์„œ viewmodel์— applicationcontext๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•

 

๋ ˆํผ๋Ÿฐ์Šค

๋”๋ณด๊ธฐ
CS/Android, Kotlin