Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Navigating Dependency Injection with Metro

Avatar for HyunWoo Lee HyunWoo Lee
December 05, 2025

Navigating Dependency Injection with Metro

GDG Devfest Incheon 2025와 KUG Seoul KMP Meetup에서 진행한 Metro로 KMP에서 의존성 주입 사용하기의 Speaker Deck입니다.
Thanks for Zac Sweers :)

Avatar for HyunWoo Lee

HyunWoo Lee

December 05, 2025
Tweet

More Decks by HyunWoo Lee

Other Decks in Programming

Transcript

  1. Kotlin User Groups Seoul Kotlin Multiplatform Meetup Metro۽ KMPীࢲ ੄ઓࢿ

    ઱ੑ ࢎਊೞӝ Navigating Dependency Injection with Metro (by Zac Sweers) HyunWoo Lee Kotlin User Groups Seoul Organizer GDG Korea Android Organizer Viva Reupublica(Toss) Android/React Native Developer
  2. Kotlin User Groups Seoul https://speakerdeck.com/l2hyunwoo/navigating- dependency-injection-with-metro Viva Republica Android/React Native

    Engineer Community & Open Source Lover - GDG Korea Android, Kotlin User Groups Seoul - Contributer & Maintainer Making a new frontier of React Native X Android Granite ❤ Apps In Toss ❤
  3. Kotlin User Groups Seoul ੄ઓࢿ ઱ੑ੉ۆ? class WeatherApp { fun

    run(location: String) { val service = WeatherService() } }
  4. Kotlin User Groups Seoul ੄ઓࢿ ઱ੑ੉ۆ? class WeatherApp { fun

    run(location: String) { val service = WeatherService() val formatter = WeatherFormatter() } }
  5. Kotlin User Groups Seoul ੄ઓࢿ ઱ੑ੉ۆ? class WeatherApp { fun

    run(location: String) { val service = WeatherService() val formatter = WeatherFormatter() val forecast = service.getForecast(location) println(formatter.format(forecast)) } }
  6. Kotlin User Groups Seoul ੄ઓࢿ ઱ੑ੉ۆ? class WeatherApp { fun

    run(location: String) { val service = WeatherService() val formatter = WeatherFormatter() / / . . . } }
  7. Kotlin User Groups Seoul ੄ઓࢿ ઱ੑ੉ۆ? class WeatherApp { private

    val service = WeatherService() private val formatter = WeatherFormatter() fun run(location: String) { / / . . . } }
  8. Kotlin User Groups Seoul ੄ઓࢿ ઱ੑ੉ۆ? class WeatherApp { private

    val service =aWeatherService() private val formatter = WeatherFormatter() fun run(location: String) { / / . . . } } ࢲ਎ 🌸 24° ب௡ 🇯🇵 25° ׏਄ 🗽 31°
  9. Kotlin User Groups Seoul Singletons class WeatherApp { private var

    service = WeatherService.getInstance() inner class Backdoor { fun setService(service: WeatherService) = // ... } }
  10. Kotlin User Groups Seoul Service Locator class WeatherApp { private

    val service: WeatherService = getApplication().getWeatherService() }
  11. Kotlin User Groups Seoul Service Locator class WeatherApp { private

    val service: WeatherService by injector.instance() }
  12. Kotlin User Groups Seoul Service Locator class WeatherApp { private

    val service: WeatherService by inject() } @Test fun exampleTest() { startKoin { modules( module { single { WeatherService() } }) } / / … }
  13. Kotlin User Groups Seoul ࣻز ઱ੑ class WeatherApp( private val

    service: WeatherService ) @Test fun exampleTest() { val app = WeatherApp(WeatherService()) / / . . . }
  14. Kotlin User Groups Seoul ࣻز ઱ੑ class WeatherApp( private val

    service: WeatherService ) @Test fun exampleTest() { val app = WeatherApp(FakeWeatherService()) / / . . . }
  15. Kotlin User Groups Seoul ࣻز ઱ੑ class WeatherApp( private val

    service: WeatherService private val formatter: WeatherFormatter ) { / / . . . } fun main() { val service = WeatherService() val formatter = WeatherFormatter() val app = WeatherApp(service, formatter) }
  16. Kotlin User Groups Seoul ࣻز ઱ੑ class WeatherApp( private val

    service: WeatherService private val formatter: WeatherFormatter ) { / / . . . } fun main() { val httpClient = HttpClient() val service = WeatherService(httpClient) val formatter = WeatherFormatter() val app = WeatherApp(service, app) }
  17. Kotlin User Groups Seoul ࣻز ઱ੑ class WeatherApp( private val

    service: WeatherService private val formatter: WeatherFormatter ) { / / . . . } fun main() { val cache = Cache() val httpClient = HttpClient(cache) val service = WeatherService(httpClient) val formatter = WeatherFormatter() val app = WeatherApp(service, app) }
  18. Kotlin User Groups Seoul class Cache(…) class HttpClient(private val cache:

    Cache) class WeatherService(private val httpClient: HttpClient) class WeatherFormatter(…) class WeatherApp( private val service: WeatherService private val formatter: WeatherFormatter ) fun main() { val cache = Cache() val httpClient = HttpClient(cache) val service = WeatherService(httpClient) val formatter = WeatherFormatter() val app = WeatherApp(service, app) } ࣻز ઱ੑ
  19. Kotlin User Groups Seoul ৵ Metroܳ ࣑݅٘աਃ? Dagger-style code gen

    Kotlin- fi rst Anvil aggrega ti on Mul ti pla tf orm Compiler plugin IDE diagnos ti cs* Metro
  20. Kotlin User Groups Seoul ৵ Metroܳ ࣑݅٘աਃ? Dagger-style code gen

    Kotlin- fi rst Anvil aggrega ti on Mul ti pla tf orm Compiler plugin IDE diagnos ti cs* Metro moshix, RCP Circuit, RCP anvil-ksp compose-lints anvil
  21. Kotlin User Groups Seoul Getting Star t ed plugins {

    id("dev.zacsweers.metro") version "0.6.6" }
  22. Kotlin User Groups Seoul Metro DI class Cache(…) class HttpClient(private

    val cache: Cache) class WeatherService(private val httpClient: HttpClient) class WeatherFormatter(…) class WeatherApp( private val service: WeatherService private val formatter: WeatherFormatter )
  23. Kotlin User Groups Seoul Metro DI @Inject class Cache(…) @Inject

    class HttpClient(private val cache: Cache) @Inject class WeatherService(private val httpClient: HttpClient) @Inject class WeatherFormatter(…) @Inject class WeatherApp( private val service: WeatherService private val formatter: WeatherFormatter )
  24. Kotlin User Groups Seoul Metro DI fun main() { val

    cache = Cache() val httpClient = HttpClient() val service = WeatherService(httpClient) val formatter = WeatherFormatter() val app = WeatherApp(service, formatter) }
  25. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp } fun main() { val app = createGraph<AppGraph>().app }
  26. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp } class HttpClient class WeatherFormatter class Cache class WeatherService
  27. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp } @Component interface AppGraph { val app: WeatherApp }
  28. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp } fun main() { val app = createGraph<AppGraph>().app }
  29. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp } fun main() { val app = createGraph<AppGraph>().app }
  30. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp } fun main() { val app = AppGraph.$$MetroGraph().app }
  31. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp } fun main() { val app = createGraph<AppGraph>().app }
  32. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @DependencyGraph.Factory interface Factory { fun create(@Provides useMetric: Boolean) : AppGraph } } fun main() { val app = createGraph<AppGraph>().app }
  33. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @DependencyGraph.Factory interface Factory { fun create(@Provides useMetric: Boolean) : AppGraph } } fun main() { val app = createGraph<AppGraph>().app }
  34. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @DependencyGraph.Factory interface Factory { fun create(@Provides useMetric: Boolean) : AppGraph } } fun main() { val app = createGraphFactory<AppGraph.Factory>() .create(useMetric = true) .app }
  35. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @Provides fun provideCache() : Cache = Cache() }
  36. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @Provides fun provideCache(fs: FileSystem) : Cache = Cache(fs) }
  37. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph :

    CacheProviders { val app: WeatherApp } interface CacheProviders { @Provides fun provideCache(fs: FileSystem) : Cache = Cache(fs) }
  38. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @Provides fun provideCache() : Cache = Cache() }
  39. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @Provides fun provideCache() : Cache = Cache() @Provides fun provideFormatterCache() : Cache = Cache() }
  40. Kotlin User Groups Seoul Metro DI @DependencyGraph interface AppGraph {

    val app: WeatherApp @Provides fun provideCache() : Cache = Cache() @Named("FormatterCache") @Provides fun provideFormatterCache() : Cache = Cache() }
  41. Kotlin User Groups Seoul Injection class HttpClient( private val cache:

    Cache, private val timeout: Duration, ) { @Inject constructor(cache: Cache) : this(cache, 30.seconds) }
  42. Kotlin User Groups Seoul Metro DI @Inject class Cache @Inject

    class HttpClient( private val cache: Cache ) @Inject class WeatherService( private val httpClient: HttpClient ) @Inject class WeatherFormatter @Inject class WeatherApp( private val service: WeatherService private val formatter: WeatherFormatter ) @DependencyGraph interface AppGraph { val app: WeatherApp } fun main() { val app = createGraph<AppGraph>().app }
  43. Kotlin User Groups Seoul Scoping @DependencyGraph interface AppGraph { val

    app: WeatherApp } @SingleIn(AppScope : : class)
  44. Kotlin User Groups Seoul Scoping @Inject @SingleIn(AppScope : : class)

    class WeatherService( private val httpClient: HttpClient )
  45. Kotlin User Groups Seoul Scoping @SingleIn(AppScope : : class) @Inject

    class WeatherService( private val httpClient: HttpClient ) @Inject class WeatherApp( private val service: WeatherService private val formatter: WeatherFormatter ) @DependencyGraph interface AppGraph { val app: WeatherApp } Always same instance
  46. Kotlin User Groups Seoul Scoping ӝࠄ੸ਵ۽ ݽٚ bindingҗ Ӓې೐ח scope

    ૑੿੉ উغয੓਺ Scope੉ ૑੿ػ ߄ੋ٬ٜী ೠ೧ࢲ double-checked lockingਵ۽ ૑ো ୡӝച Scope਷ bindingਸ ੿੄ೞח ଃীࢲ ࢶ঱, ੉ܳ ࢎਊೞח ଃীࢲ scopeਸ ঌ ೙ਃח হ਺ ౠ੿ binding type਷ scope ૑੿ ࠛо
  47. Kotlin User Groups Seoul @Binds interface Bindings { @Binds fun

    bind(int: Int) : Number @Binds val String.bind: CharSequence }
  48. Kotlin User Groups Seoul @Binds @Binds fun bind(int: Int) :

    Number @Inject class HttpClient(timeoutMillis: Number)
  49. Kotlin User Groups Seoul @Binds @Binds fun bind(int: Int) :

    Number @Inject class HttpClient(timeoutMillis: Number)
  50. Kotlin User Groups Seoul @Binds @Binds fun bind(int: Int) :

    Number @Inject class HttpClient(timeoutMillis: Number)
  51. Kotlin User Groups Seoul Assisted Injection @Inject class UserRepository( val

    id: String, val httpClient: HttpClient, val db: UserDb )
  52. Kotlin User Groups Seoul Assisted Injection @Inject class UserRepository( @Assisted

    val id: String, val httpClient: HttpClient, val db: UserDb )
  53. Kotlin User Groups Seoul Assisted Injection @Inject class UserRepository( @Assisted

    val id: String, val httpClient: HttpClient, val db: UserDb ) { @AssistedFactory interface Factory { fun create(id: String) : UserRepository } }
  54. Kotlin User Groups Seoul Assisted Injection @Inject class UserRepository( @Assisted

    val id: String, val httpClient: HttpClient, val db: UserDb ) { @AssistedFactory interface Factory { fun create(id: String) : UserRepository } }
  55. Kotlin User Groups Seoul Assisted Injection @Inject class WeatherApp( val

    factory: UserRepository.Factory ) { fun run() { val userRepo = factory.create("d3938c4891ae") } } @Inject class UserRepository( @Assisted val id: String, val httpClient: HttpClient, val db: UserDb ) { @AssistedFactory interface Factory { fun create(id: String) : UserRepository } }
  56. Kotlin User Groups Seoul Multibindings @DependencyGraph interface AppGraph { val

    interceptors: Set<Interceptor> val eventHandlers: Map<String, EventHandler> }
  57. Kotlin User Groups Seoul Multibindings @DependencyGraph interface AppGraph { val

    interceptors: Set<Interceptor> val eventHandlers: Map<String, EventHandler> @Provide @IntoSet fun provideLoggingInterceptor() : Interceptor = LoggingInterceptor() }
  58. Kotlin User Groups Seoul Multibindings @DependencyGraph interface AppGraph { val

    interceptors: Set<Interceptor> val eventHandlers: Map<String, EventHandler> @Provide @IntoSet fun provideLoggingInterceptor() : Interceptor = LoggingInterceptor() } @Inject @IntoMap @StringKey("ping") class PingHandler : EventHandler
  59. Kotlin User Groups Seoul Multibindings @DependencyGraph interface AppGraph { @Multibinds

    val interceptors: Set<Interceptor> @Multibinds val eventHandlers: Map<String, EventHandler> }
  60. Kotlin User Groups Seoul Multibindings @DependencyGraph interface AppGraph { @Multibinds(allowEmpty

    = true) val interceptors: Set<Interceptor> @Multibinds(allowEmpty = true) val eventHandlers: Map<String, EventHandler> }
  61. Kotlin User Groups Seoul Aggregation @DependencyGraph(scope = AppScope : :

    class) interface AppGraph @SingleIn(scope = AppScope : : class)
  62. Kotlin User Groups Seoul Aggregation @DependencyGraph(AppScope : : class) /

    / @SingleIn(AppScope : : class) / / Implicit! interface AppGraph
  63. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache } @Inject class CacheImpl(…) : Cache
  64. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache } @Inject class CacheImpl(…) : Cache
  65. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache @Binds val CacheImpl.bind: Cache } @Inject class CacheImpl(…) : Cache
  66. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache } @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache
  67. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph : CacheImpl.AppScope$$Contribution { val cache: Cache } @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache { @MetroContribution interface AppScope$$Contribution { @Binds val CacheImpl.bind: Cache } }
  68. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache } @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache
  69. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache } @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache, Closeable
  70. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache } @ContributesBinding(AppScope : : class, binding = binding<Cache>()) @Inject class CacheImpl(…) : Cache, Closeable
  71. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache<Forecast> } @ContributesBinding(AppScope : : class, binding = binding<Cache<Forecast > > ()) @Inject class CacheImpl(…) : Cache<Forecast>, Closeable
  72. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val cache: Cache } @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache
  73. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val interceptors: Set<Interceptor> } @ContributesIntoSet(AppScope : : class) @Inject class LogcatInterceptor(…) : Interceptor
  74. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph { val eventHandlers: Map<String, EventHandler> } @Inject @ContributesIntoMap(AppScope : : class) @StringKey("ping") class PingHandler : EventHandler
  75. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph @ContributesTo(AppScope : : class) interface Accessors { val eventHandlers: Map<String, EventHandler> }
  76. Kotlin User Groups Seoul What's a Contribution? @DependencyGraph(AppScope : :

    class) interface AppGraph : Accessors @ContributesTo(AppScope : : class) interface Accessors { val eventHandlers: Map<String, EventHandler> }
  77. Kotlin User Groups Seoul @DependencyGraph(AppScope : : class) interface AppGraph

    { val cache: Cache val interceptors: Set<Interceptor> val eventHandlers: Map<String, EventHandler> } @ContributesIntoSet(AppScope : : class) @Inject class LogcatInterceptor(…) : Interceptor @Inject @ContributesIntoMap(AppScope : : class) @StringKey("ping") class PingHandler : EventHandler @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache :lib - network :app :lib - events :lib - cache
  78. Kotlin User Groups Seoul Intrinsics Provider Lazy @Inject class HttpClient(val

    cache: Cache) { init { val cacheInstance = cache } }
  79. Kotlin User Groups Seoul Intrinsics Provider Lazy @Inject class HttpClient(val

    cache: Provider<Cache>) { init { val cacheInstance = cache() } }
  80. Kotlin User Groups Seoul Intrinsics Provider Lazy @Inject class HttpClient(val

    cache: Lazy<Cache>) { init { val cacheInstance = cache.value } }
  81. Kotlin User Groups Seoul Graph Extensions @GraphExtension interface LoggedInGraph {

    val user: User } @DependencyGraph interface AppGraph { val loggedInGraph: LoggedInGraph }
  82. Kotlin User Groups Seoul Graph Extensions Factories that you can

    declare instead @GraphExtension interface LoggedInGraph { val user: User } @DependencyGraph interface AppGraph { val loggedInGraph: LoggedInGraph }
  83. Kotlin User Groups Seoul Graph Extensions Factories that you can

    declare instead @GraphExtension interface LoggedInGraph { val user: User @GraphExtension.Factory interface Factory { fun create(@Provides id: String) : LoggedInGraph } } @DependencyGraph interface AppGraph { val loggedInGraphFactory: LoggedInGraph.Factory }
  84. Kotlin User Groups Seoul Graph Extensions Factories that you can

    declare instead @GraphExtension interface LoggedInGraph { val user: User @GraphExtension.Factory interface Factory { fun createLoggedInGraph() : LoggedInGraph } } @DependencyGraph interface AppGraph : LoggedInGraph.Factory / / usage val loggedInGraph = appGraph.createLoggedInGraph()
  85. Kotlin User Groups Seoul Graph Extensions Factories that you can

    declare instead Scope annotations @GraphExtension @SingleIn(LoggedInScope : : class) interface LoggedInGraph { val user: User }
  86. Kotlin User Groups Seoul Graph Extensions Factories that you can

    declare instead Scope annotations Aggregation scopes @GraphExtension(LoggedInScope : : class) interface LoggedInGraph { val user: User }
  87. Kotlin User Groups Seoul Graph Extensions Factories that you can

    declare instead Scope annotations Aggregation scopes Provider/Binds callables @GraphExtension(LoggedInScope : : class) interface LoggedInGraph { val user: User @Provides fun provideUser() : User = … }
  88. Kotlin User Groups Seoul Graph Extensions Factories that you can

    declare instead Scope annotations Aggregation scopes Provider/Binds callables Their own extensions! @GraphExtension interface LoggedInActivityGraph { val user: User val activity: Activity } @GraphExtension interface LoggedInGraph { val user: User val loggedInActivityGraph: LoggedInActivityGraph } @DependencyGraph interface AppGraph { val loggedInGraph: LoggedInGraph }
  89. Kotlin User Groups Seoul о੢ рױೠ Gradle ౵੉೐ۄੋ @DependencyGraph interface

    AppGraph { val app: WeatherApp } kotlinc (Frontend and Backend) compileKotlin .class f i les
  90. Kotlin User Groups Seoul ݣ౭೒ۖಬীࢲח? @DependencyGraph interface AppGraph { val

    app: WeatherApp } kotlinc (Frontend and Backend) compileKotlin .class .js .wasm . . .
  91. Kotlin User Groups Seoul KSP ࠽٘ ౵੉೐ۄੋ @DependencyGraph interface AppGraph

    { val app: WeatherApp } <compiled binaries> kotlinc (Frontend only) KSP source f i les kotlinc (Frontend and Backend) compileKotlin
  92. Kotlin User Groups Seoul kotlinc (Frontend only) Stub gen .java

    f i les Kapt (javac) Kapt source f i les kotlinc (Frontend and Backend) compileKotlin .class f i les KAPTܳ ࢎਊೠ׮ݶ?
  93. Kotlin User Groups Seoul kotlinc (Frontend only) Stub gen .java

    f i les Kapt (javac) Kapt source f i les kotlinc (Frontend and Backend) compileKotlin .class f i les javac compileJava More .class f i les KAPTܳ ࢎਊೠ׮ݶ?
  94. Kotlin User Groups Seoul kotlinc (Frontend only) Stub gen .java

    f i les Kapt (javac) Kapt source f i les kotlinc (Frontend and Backend) compileKotlin .class f i les javac compileJava More .class f i les HILT ࠽٘ ౵੉೐ۄੋ javac :hiltJavaCompileDebug Even more .class f i les
  95. Kotlin User Groups Seoul kotlinc (Frontend only) Stub gen .java

    f i les Kapt (javac) Kapt source f i les kotlinc (Frontend and Backend) compileKotlin .class f i les javac compileJava More .class f i les HILT ࠽٘ ౵੉೐ۄੋ javac :hiltJavaCompileDebug Even more .class f i les
  96. Kotlin User Groups Seoul Metro Build Pipeline @DependencyGraph interface AppGraph

    { val app: WeatherApp } kotlinc (Frontend and Backend) compileKotlin binary f i les
  97. Kotlin User Groups Seoul Metro Build Pipeline @DependencyGraph interface AppGraph

    { val app: WeatherApp } kotlinc (Frontend and Backend) compileKotlin binary f i les
  98. Kotlin User Groups Seoul Metro Build Pipeline binary f i

    les Frontend Backend Source f i les
  99. Kotlin User Groups Seoul Metro Build Pipeline binary f i

    les Frontend Backend FIR IR Lowering Parse/PSI Source f i les
  100. Kotlin User Groups Seoul Metro Build Pipeline binary f i

    les Frontend Backend FIR IR Lowering Parse/PSI f i r2ir Source f i les
  101. Kotlin User Groups Seoul Declaration ࢤࢿ Constructor-injected classes/providers @Inject class

    Cache { / / Generated by Metro class $$MetroFactory : Factory<Cache> { constructor() companion object { fun create() : $$MetroFactory fun newInstance() : Cache } } }
  102. Kotlin User Groups Seoul Declaration ࢤࢿ Constructor-injected classes/providers Assisted factory

    impls @AssistedFactory interface Factory { fun create(id: String) : UserRepository / / Generated by Metro class $$Impl : Factory }
  103. Kotlin User Groups Seoul Declaration ࢤࢿ Constructor-injected classes/providers Assisted factory

    impls Contribution interfaces @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache { / / Generated by Metro @MetroContribution interface AppScope$$Contribution }
  104. Kotlin User Groups Seoul Declaration ࢤࢿ @DependencyGraph.Factory interface Factory {

    fun create() : AppGraph / / Generated in FIR class $$Impl : Factory { constructor() } }
  105. Kotlin User Groups Seoul Declaration ࢤࢿ @DependencyGraph.Factory interface Factory {

    fun create() : AppGraph / / Generated in FIR class $$Impl : Factory { constructor() } } @DependencyGraph.Factory interface Factory { fun create() : AppGraph class $$Impl : Factory { constructor() { } / / Implemented in IR override fun create() : AppGraph = AppGraph.$$MetroGraph() } }
  106. Kotlin User Groups Seoul Super t ype ࢤࢿ @DependencyGraph(AppScope :

    : class) interface AppGraph @ContributesBinding(AppScope : : class) @Inject class CacheImpl(…) : Cache { / / Generated by Metro @MetroContribution interface AppScope$$Contribution } @ContributesTo(AppScope : : class) interface NetworkProviders { / / . . . }
  107. Kotlin User Groups Seoul Checkers ױ ೞա੄ ୶࢚ ೣࣻ݅ оઉঠ

    ೞח૑ ೣࣻо dependency graphܳ ߈ജೞח૑ ਬബೠ ഋక੄ ಁ۞޷ఠܳ о૑Ҋ ੓ח૑ …੉৻ীب 100ѐ ؊ object DependencyGraphCreatorChecker
  108. Kotlin User Groups Seoul Metro Build Pipeline binary f i

    les Frontend Backend FIR IR Lowering Parse/PSI f i r2ir Source f i les
  109. Kotlin User Groups Seoul IR ߸ജ 1. FIRױীࢲ ࢤࢿೠ Binds

    ೣٜࣻਸ पઁ۽ ҳഅೞӝ 2. Ӓ ৻ী աݠ૑ ݽٚ Ѫٜী ؀ೠ ߸ജ ੘স
  110. Kotlin User Groups Seoul Metro IR Pipeline 1. Ӓې೐о ইצ

    ௿ېझٜਸ ݢ੷ ߸ജ 2. ੄ઓࢿ Ӓې೐ܳ ߸ജ A. Ӓې೐ ҳࢿ ؘ੉ఠ(߄ੋ٬, ܖ౟, GraphExtension) ࣻ૘ B. GraphExtension ୊ܻ C. BindingGraph ࢤࢿ D. ਬബࢿ Ѩࢎ E. IR Ӓې೐ ҳഅ • ߄ੋ٬ٜ ଻ਕ֍ӝ • Tarjan validation(ъೠਃࣗ Ѿ೤ Ѩ ࢎ) + Kahn sorting(ਤ࢚੿۳) • Ѿҗ ߈ജ • ੿۳ػ(top sorted) • ب׳ оמೠ(reachable) • ૑ো୊ܻ೧ঠ ೡ(deferred) ఃٜ
  111. Kotlin User Groups Seoul @Inject @SingleIn(AppScope : : class) class

    WeatherService( httpClient: HttpClient ) @Inject class WeatherFormatter(…) @Inject class WeatherApp( service: WeatherService formatter: WeatherFormatter ) @DependencyGraph @SingleIn(AppScope : : class) interface AppGraph { val app: WeatherApp @Provides fun provideCache() : Cache = Cache() @Provides fun provideHttpClient(cache: Cache) : HttpClient = HttpClient(cache) } Metro IR Pipeline
  112. Kotlin User Groups Seoul Metro IR Pipeline @DependencyGraph @SingleIn(AppScope :

    : class) interface AppGraph { val app: WeatherApp @Provides fun provideCache() : Cache = Cache() @Provides fun provideHttpClient(cache: Cache) : HttpClient = HttpClient(cache) }
  113. Kotlin User Groups Seoul Metro IR Pipeline Scope — @SingleIn(AppScope

    : : class) @DependencyGraph interface AppGraph { val app: WeatherApp @Provides fun provideCache() : Cache = Cache() @Provides fun provideHttpClient( cache: Cache ) : HttpClient = HttpClient(cache) }
  114. Kotlin User Groups Seoul Metro IR Pipeline Scope — @SingleIn(AppScope

    : : class) IrBinding.Provided — Cache @DependencyGraph interface AppGraph { val app: WeatherApp @Provides fun provideHttpClient( cache: Cache ) : HttpClient = HttpClient(cache) }
  115. Kotlin User Groups Seoul Metro IR Pipeline Scope — @SingleIn(AppScope

    : : class) IrBinding.Provided — Cache IrBinding.Provided — HttpClient @DependencyGraph interface AppGraph { val app: WeatherApp }
  116. Kotlin User Groups Seoul Metro IR Pipeline Scope — @SingleIn(AppScope

    : : class) IrBinding.Provided — Cache IrBinding.Provided — HttpClient Accessor — app: WeatherApp @DependencyGraph interface AppGraph
  117. Kotlin User Groups Seoul Metro IR Pipeline WeatherApp class HttpClient

    class WeatherFormatter class Cache class WeatherService BindingLookup Cache: IrBinding.Provided HttpClient: IrBinding.Provided
  118. Kotlin User Groups Seoul Metro IR Pipeline WeatherApp class HttpClient

    class WeatherFormatter class Cache class WeatherService
  119. Kotlin User Groups Seoul Metro IR Pipeline WeatherApp (IrBinding.ConstructorInjected) WeatherFormatter

    (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) Cache (IrBinding.Provided) HttpClient (IrBinding.Provided)
  120. Kotlin User Groups Seoul Metro IR Pipeline Tarjan's Algorithm WeatherApp

    (IrBinding.ConstructorInjected) WeatherFormatter (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) Cache (IrBinding.Provided) HttpClient (IrBinding.Provided)
  121. Kotlin User Groups Seoul Metro IR Pipeline Kahn's Topo Sor

    t WeatherApp (IrBinding.ConstructorInjected) WeatherFormatter (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) Cache (IrBinding.Provided) HttpClient (IrBinding.Provided)
  122. Kotlin User Groups Seoul Metro IR Pipeline Kahn's Topo Sor

    t Cache (IrBinding.Provided) HttpClient (IrBinding.Provided) WeatherFormatter (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) WeatherApp (IrBinding.ConstructorInjected)
  123. Kotlin User Groups Seoul Metro IR Pipeline Cache (IrBinding.Provided) HttpClient

    (IrBinding.Provided) WeatherFormatter (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) WeatherApp (IrBinding.ConstructorInjected)
  124. Kotlin User Groups Seoul Metro IR Pipeline @DependencyGraph @SingleIn(AppScope :

    : class) interface AppGraph { val app: WeatherApp } Cache (IrBinding.Provided) HttpClient (IrBinding.Provided) WeatherFormatter (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) WeatherApp (IrBinding.ConstructorInjected)
  125. Kotlin User Groups Seoul Metro IR Pipeline class $$MetroGraph :

    AppGraph { } Cache (IrBinding.Provided) HttpClient (IrBinding.Provided) WeatherFormatter (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) WeatherApp (IrBinding.ConstructorInjected)
  126. Kotlin User Groups Seoul Metro IR Pipeline class $$MetroGraph :

    AppGraph { } ProviderFieldCollector Cache (IrBinding.Provided) HttpClient (IrBinding.Provided) WeatherFormatter (IrBinding.ConstructorInjected) WeatherService (IrBinding.ConstructorInjected) WeatherApp (IrBinding.ConstructorInjected)
  127. Kotlin User Groups Seoul Metro IR Pipeline class $$MetroGraph :

    AppGraph { } WeatherService ProviderFieldCollector
  128. Kotlin User Groups Seoul Metro IR Pipeline Cache (IrBinding.Provided) HttpClient

    (IrBinding.Provided) WeatherFormatter (IrBinding.ConstructorInjected) WeatherApp (IrBinding.ConstructorInjected) class $$MetroGraph : AppGraph { private val weatherServiceProvider: Provider<WeatherService> }
  129. Kotlin User Groups Seoul Metro IR Pipeline WeatherFormatter (IrBinding.ConstructorInjected) WeatherApp

    (IrBinding.ConstructorInjected) class $$MetroGraph : AppGraph { private val weatherServiceProvider: Provider<WeatherService> = DoubleCheck.provider(…) }
  130. Kotlin User Groups Seoul Metro IR Pipeline WeatherFormatter (IrBinding.ConstructorInjected) WeatherApp

    (IrBinding.ConstructorInjected) class $$MetroGraph : AppGraph { private val weatherServiceProvider: Provider<WeatherService> = DoubleCheck.provider( WeatherService.$$MetroFactory.create( $$HttpClientProvider.create( $$CacheProvider() ) ) ) }
  131. Kotlin User Groups Seoul Metro IR Pipeline class $$MetroGraph :

    AppGraph { private val weatherServiceProvider: Provider<WeatherService> = DoubleCheck.provider( WeatherService.$$MetroFactory.create( $$HttpClientProvider.create( $$CacheProvider() ) ) ) override val app: WeatherApp get() = WeatherApp$$MetroFactory.create( this.weatherServiceProvider, WeatherFormatter$$MetroFactory.create() ).invoke() }
  132. Kotlin User Groups Seoul Metro IR Pipeline class $$MetroGraph :

    AppGraph { private val weatherServiceProvider: Provider<WeatherService> = DoubleCheck.provider( WeatherService.$$MetroFactory.create( $$HttpClientProvider.create( $$CacheProvider() ) ) ) override val app: WeatherApp get() = WeatherApp$$MetroFactory.create( this.weatherServiceProvider, WeatherFormatter$$MetroFactory.create() ).invoke() }
  133. Kotlin User Groups Seoul ੉৻ী ׮ܲ Ѫٜ • ૐ࠙࠽٘-ౠ൤ য֢ప੉࣌

    ҙ۲ ઱੄ • createGraph() ৬ createGraphFactory() ഐ୹ ߸ഋ val graph = createGraph<AppGraph>() val graph = AppGraph.$$MetroGraph()
  134. Kotlin User Groups Seoul Advanced Usage Binding containers @Includes Member

    injection Valid cycles Optional Top-level function injection Contribution replacements/excludes Compose integration Repor t s Circuit
  135. Kotlin User Groups Seoul Component Interop @Component interface StartupComponent {

    val httpClient: HttpClient / / . . . } @DependencyGraph interface AppGraph { @DependencyGraph.Factory interface Factory { fun create( @Includes startupComponent: StartupComponent ) : AppGraph } } https://zacsweers.github.io/metro/latest/adoption.html
  136. Kotlin User Groups Seoul Annotations Interop @Component interface StartupComponent {

    val httpClient: HttpClient } class HttpClient @Inject constructor( val cache: Provider<Cache> ) metro { interop { enableDagger() enableAnvil() } } https://zacsweers.github.io/metro/latest/adoption.html