Skip to content

Refactor: Replace kotlin-inject with Metro for dependency injection#155

Merged
Rolf-Smit merged 1 commit into
mainfrom
feature/refactor-dependency-injection-to-metro
May 7, 2026
Merged

Refactor: Replace kotlin-inject with Metro for dependency injection#155
Rolf-Smit merged 1 commit into
mainfrom
feature/refactor-dependency-injection-to-metro

Conversation

@Rolf-Smit
Copy link
Copy Markdown
Contributor

@Rolf-Smit Rolf-Smit commented Apr 23, 2026

Upside:

  • Metro is a Kotlin compiler plugin, so it generates .class files directly during IR transformation rather than producing source files like KSP. This removes the need for the KSP plugin and seems to also eliminate per iOS target wiring in the build script, this is nice.

Downside:

  • @Inject on top-level functions works at compile time, but the generated types are not resolved by the IDE ("Unresolved reference" errors). Wrapper classes with @Inject on the constructor and a @Composable operator fun invoke() seem to be the recommended approach to avoid this. However, this is not ideal as it adds boilerplate (see: https://zacsweers.github.io/metro/latest/installation/#ide-support).
  • Metro graphs cannot have constructor parameters, and platform specific modules cannot extend the shared graph with additional bindings (only the reverse direction is supported via @GraphExtension it seems). So platform dependencies must be constructed manually. Currently there is only one (PlatformFileDataSource), but if more are added this might get messy. kotlin-inject avoided this through component inheritance.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 23, 2026

Codecov Report

❌ Patch coverage is 2.00000% with 49 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.79%. Comparing base (566354c) to head (853b49c).

Files with missing lines Patch % Lines
...tech/app/abysner/presentation/MainNavController.kt 0.00% 15 Missing ⚠️
...abysner/presentation/screens/planner/PlanScreen.kt 0.00% 10 Missing ⚠️
...er/presentation/screens/DiveConfigurationScreen.kt 0.00% 7 Missing ⚠️
...app/abysner/presentation/screens/SettingsScreen.kt 0.00% 5 Missing ⚠️
...s/terms_and_conditions/TermsAndConditionsScreen.kt 0.00% 5 Missing ⚠️
.../abysner/presentation/screens/about/AboutScreen.kt 20.00% 3 Missing and 1 partial ⚠️
.../kotlin/org/neotech/app/abysner/di/AppComponent.kt 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #155      +/-   ##
==========================================
- Coverage   70.08%   69.79%   -0.30%     
==========================================
  Files         145      144       -1     
  Lines        8107     8140      +33     
  Branches     1032     1038       +6     
==========================================
- Hits         5682     5681       -1     
- Misses       1912     1946      +34     
  Partials      513      513              
Flag Coverage Δ
domain 77.88% <ø> (ø)
presentation 67.84% <2.00%> (-0.36%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Rolf-Smit Rolf-Smit force-pushed the feature/refactor-dependency-injection-to-metro branch 2 times, most recently from 24eeaf7 to 2cafd19 Compare April 23, 2026 16:26
Upside:
- Metro is a Kotlin compiler plugin, so it generates .class files directly during IR transformation rather than producing source files like KSP. This removes the need for the KSP plugin and seems to also eliminate per iOS target wiring in the build script, this is nice.

Downside:
- `@Inject` on top-level functions works at compile time, but the generated types are not resolved by the IDE ("Unresolved reference" errors). Wrapper classes with `@Inject` on the constructor and a `@Composable operator fun invoke()` seem to be the recommended approach to avoid this. However, this is not ideal as it adds boilerplate (see: https://zacsweers.github.io/metro/latest/installation/#ide-support).
- Metro graphs cannot have constructor parameters, and platform specific modules cannot extend the shared graph with additional bindings (only the reverse direction is supported via `@GraphExtension` it seems). So platform dependencies must be constructed manually. Currently there is only one (`PlatformFileDataSource`), but if more are added this might get messy. kotlin-inject avoided this through component inheritance.
@Rolf-Smit Rolf-Smit force-pushed the feature/refactor-dependency-injection-to-metro branch from 2cafd19 to 853b49c Compare May 7, 2026 01:14
@Rolf-Smit Rolf-Smit merged commit 8896d5f into main May 7, 2026
4 checks passed
@Rolf-Smit Rolf-Smit deleted the feature/refactor-dependency-injection-to-metro branch May 7, 2026 09:36
@github-actions github-actions Bot locked and limited conversation to collaborators May 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants