Skip to content

Migrate Hilt dependency injection snippets - #1172

Open
djubinville wants to merge 3 commits into
android:mainfrom
djubinville:djubinville/di-hilt-snippets
Open

djubinville wants to merge 3 commits into
android:mainfrom
djubinville:djubinville/di-hilt-snippets

Conversation

@djubinville

@djubinville djubinville commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Pages:

List of modifications:

  • Hilt-android page: Replaced placeholder { ... } in class and interface bodies (android_di_hilt_android_application, android_di_hilt_android_entry_point, android_di_hilt_android_constructor_injection, android_di_hilt_android_binds, android_di_hilt_android_predefined_qualifiers, android_di_hilt_android_activity_scoped, android_di_hilt_android_application_context, android_di_hilt_android_activity_context) with { /* ... */ } so the declarations compile in Kotlin while preserving the single-line body structure from the guide.
  • Hilt-android page: Expanded the placeholder ... parameter list in ContentProvider.query(...) to the full 5-parameter Android SDK ContentProvider.query signature in android_di_hilt_android_entry_point_accessors so the override compiles (held pending docs team ruling on H-3).
  • Hilt-multi-module page: Replaced placeholder { ... } in the class body (android_di_hilt_multimodule_analytics_adapter) with { /* ... */ } so the declaration compiles in Kotlin while preserving the single-line body structure from the guide.
  • Hilt-jetpack page: Replaced placeholder { ... } in the class body (android_di_hilt_jetpack_worker) with { /* ... */ } and formatted @AssistedFactory interface Factory (android_di_hilt_jetpack_assisted_viewmodel) via spotlessApply.
  • Hilt-jetpack page: Updated override fun getWorkManagerConfiguration() to override val workManagerConfiguration: Configuration property syntax required by WorkManager 2.9+ Configuration.Provider in Kotlin in android_di_hilt_jetpack_application.
  • Hilt-testing page: Replaced placeholder { ... } in class bodies (android_di_hilt_testing_unit_test, android_di_hilt_testing_uninstall_modules) with { /* ... */ } and placed unit/Robolectric snippets (android_di_hilt_testing_unit_test, android_di_hilt_testing_robolectric_config) in src/test/.../HiltTesting.kt and instrumentation test snippets in src/androidTest/.../HiltTesting.kt.

Snippets not migrated:

  • Hilt-android page: Lines 39-51, 60-91, and 101-119 because they are Gradle build configuration and dependency blocks.
  • Hilt-jetpack page: Lines 105-117 and 158-173 because they are Gradle dependency blocks.
  • Hilt-testing page: Lines 56-71 and 151-158 because they are Gradle build configuration and dependency blocks.

@djubinville
djubinville marked this pull request as ready for review October 13, 2026 19:56
@djubinville

Copy link
Copy Markdown
Contributor Author

Resolved review findings across HiltAndroid.kt, HiltJetpack.kt, HiltTesting.kt, and compose/snippets/build.gradle.kts:

  • Replaced unbalanced [START_EXCLUDE silent] object-splitting blocks in android_di_hilt_android_singleton_scoped, android_di_hilt_android_application_context, and android_di_hilt_android_activity_context with balanced /* / */ silent-exclude comment blocks inside a single enclosing wrapper object, plus a compiled twin outside [END ...].
  • Preserved original ... placeholders verbatim on the guide pages in android_di_hilt_android_inject_qualified, android_di_hilt_jetpack_nav3, android_di_hilt_testing_unit_test, and android_di_hilt_testing_rule_chain using silent-excluded /* / */ blocks alongside compiled calls, and removed unused ExampleService, expected, and actual declarations.
  • Changed all file-local helpers and snippet wrappers in HiltTesting.kt and non-Dagger-processed wrappers in HiltAndroid.kt/HiltJetpack.kt to private.
  • Note on compileOnly(libs.hilt.compiler) vs private object wrappers: compileOnly(libs.hilt.compiler) + ksp(libs.dagger.compiler) is intentionally used in compose/snippets/build.gradle.kts because Hilt's whole-module processor rejects private object snippet wrappers and multiple @HiltAndroidApp classes across :compose:snippets, and internal is retained on wrappers/helpers in src/main that directly enclose @Inject or @Module declarations because dagger-compiler KSP rejects private @Inject targets and private @Module enclosures.

@djubinville
djubinville requested a review from a team as a code owner October 13, 2026 19:56
@djubinville
djubinville requested a review from rebeccasg October 13, 2026 19:56
@snippet-bot

snippet-bot Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Here is the summary of changes.

You are about to add 41 region tags.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@djubinville

Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed (Commit 808e220b)

1. Local Build & Spotless Verification (G1)

Ran :compose:snippets:spotlessCheck and :compose:snippets:build locally on commit 808e220b:

$ ./gradlew :compose:snippets:spotlessCheck :compose:snippets:build --console=plain
...
> Task :compose:snippets:spotlessCheck
> Task :compose:snippets:kspDebugKotlin
> Task :compose:snippets:compileDebugKotlin
> Task :compose:snippets:hiltJavaCompileDebug
> Task :compose:snippets:hiltJavaCompileRelease
> Task :compose:snippets:compileDebugUnitTestKotlin
> Task :compose:snippets:testDebugUnitTest
> Task :compose:snippets:lintDebug
> Task :compose:snippets:check
> Task :compose:snippets:build

BUILD SUCCESSFUL in 3m 20s
123 actionable tasks: 35 executed, 88 up-to-date

2. Changes Applied (H-1–H-5, G2)

  • H-1 (compose/snippets/build.gradle.kts, gradle/libs.versions.toml, HiltAndroid.kt, HiltMultiModule.kt, HiltJetpack.kt):
    • Restored ksp(libs.hilt.compiler) in compose/snippets/build.gradle.kts and removed dagger-compiler from gradle/libs.versions.toml and compose/snippets/build.gradle.kts.
    • Replaced private object wrappers around Hilt-annotated snippet groups with internal object wrappers (matching existing main precedent in ComposeWithOtherLibraries.kt object HiltExample3, object HiltViewModel, and object HiltViewModelBackStack), and kept a single active @HiltAndroidApp class ExampleApplication in :compose:snippets (hiding the duplicate @HiltAndroidApp in HiltAndroid.kt from KSP via [START_EXCLUDE silent]) so real Hilt KSP codegen and hiltJavaCompileDebug / hiltJavaCompileRelease run and succeed.
    • Note on alternative architecture (Option 2 / D25): If repo owner approval is granted under D25 (which currently restricts migrations to existing Gradle modules unless approved by repo owners), a dedicated :hilt Gradle module could also be introduced in the future to isolate @HiltAndroidApp and Hilt KSP codegen from :compose:snippets.
  • H-2 (HiltAndroid.kt, HiltMultiModule.kt, HiltJetpack.kt, HiltTesting.kt): Standardized all 12 single-line { ... } class/interface body placeholders to one-line { /* ... */ } (matching PR Migrate Dependency injection intro and manual DI snippets #1170, PR Migrate Dagger dependency injection snippets #1171, and existing main convention) and updated the PR description accordingly.
  • H-3 (HiltAndroid.kt): Held the 5-parameter ContentProvider.query(...) signature in android_di_hilt_android_entry_point_accessors pending the docs team ruling, as requested.
  • H-4 (src/test/.../HiltTesting.kt, src/androidTest/.../HiltTesting.kt, compose/snippets/build.gradle.kts): Moved android_di_hilt_testing_unit_test and android_di_hilt_testing_robolectric_config to compose/snippets/src/test/java/com/example/compose/snippets/architecture/di/HiltTesting.kt, removed androidTestImplementation(libs.robolectric), and added testImplementation(libs.robolectric) and testImplementation(libs.hilt.android.testing).
  • H-5 (gradle/libs.versions.toml): Split androidx-hilt-work onto its own androidxHiltWork = "1.4.0" version ref instead of reusing hiltNavigationCompose.
  • G2 (Shared build configuration with PR Migrate Dagger dependency injection snippets #1171): Noted the intentional gradle/libs.versions.toml and compose/snippets/build.gradle.kts overlap with PR Migrate Dagger dependency injection snippets #1171; whichever PR merges second will be rebased immediately onto main.

3. Documented Rule Bypasses (android-snippets-experimental)

  • D10 & D26a Bypass (H-1):
    • Rule Violated: D10 ("Every snippet group MUST be isolated inside a private object or private class wrapper") and D26a (prohibiting internal wrappers as a visibility workaround).
    • Reasoning: Hilt KSP (ksp(libs.hilt.compiler)) explicitly rejects @AndroidEntryPoint, @HiltViewModel, @Module, and @EntryPoint declarations nested inside private classes/objects (@AndroidEntryPoint may not be enclosed in private classes) and requires package-visible (internal or public) enclosing wrappers so generated Java classes in the same package can reference them (as already done on main in ComposeWithOtherLibraries.kt). Additionally, Hilt KSP forbids multiple @HiltAndroidApp classes in a single Gradle module (Cannot process multiple app roots in the same module), requiring the duplicate @HiltAndroidApp annotation in HiltAndroid.kt to be excluded via [START_EXCLUDE silent] unless a dedicated :hilt module is approved under D25.
    • Recommended Rule Update: Update D10 and D26a in SKILL.md to permit internal wrapper objects when required by Hilt/Dagger KSP codegen, and document how to handle multiple @HiltAndroidApp snippets within a single module (or authorize a dedicated :hilt module under D25).
  • D23 Step 3 Bypass (G3 & H-2):
    • Rule Violated: D23 Step 3 ("Any modifications to original snippet logic or visible lines MUST be reverted unless strictly required to compile").
    • Reasoning: Original DAC blocks use { ... } on single-line class/interface declarations, which is invalid Kotlin syntax, while Spotless (ktlint:standard:no-empty-class-body) rejects empty {} inside region tags where @Suppress cannot be placed without rendering. Replacing { ... } with { /* ... */ } preserves the single-line declaration structure and matches existing main (SystemBroadcastReceiver.kt, QuickSettingsTile.kt), PR Migrate Dependency injection intro and manual DI snippets #1170, and PR Migrate Dagger dependency injection snippets #1171.
    • Recommended Rule Update: Update D23 Step 3 in SKILL.md to explicitly allow { /* ... */ } for single-line { ... } class/interface body placeholders in DAC snippets.
  • D23 Step 3 Bypass (H-3 — ContentProvider.query in HiltAndroid.kt):
    • Rule Violated: D23 Step 3 (modifying visible lines in android_di_hilt_android_entry_point_accessors).
    • Reasoning: The original DAC snippet writes override fun query(...): Cursor, which is invalid Kotlin syntax because ContentProvider.query is an abstract 5-parameter method. Per reviewer guidance in H-3 ("Hold until the docs team rules on it"), the expanded 5-parameter override fun query(...) signature is retained and documented in the PR description.
    • Recommended Rule Update: Update D23 Step 3 in SKILL.md to clarify whether override fun method(...) placeholders in DAC snippets should be expanded to the full SDK parameter list (documented in the PR body) or hidden with a [START_EXCLUDE silent] compilable twin.
  • D23 Step 1 Bypass (G4 — HiltTesting.kt):
    • Rule Violated: D23 Step 1 ("You MUST keep exact fidelity with the original snippet in the documentation").
    • Reasoning: assertEquals(1, 1) in android_di_hilt_testing_unit_test is hidden via [START_EXCLUDE silent] and paired with // assertEquals(...) outside the exclude block because the original DAC snippet uses literal assertEquals(...) syntax, which does not compile in Kotlin.
    • Recommended Rule Update: Update D23 Step 1 in SKILL.md to explicitly document the [START_EXCLUDE silent] compilable-twin pattern when original DAC snippet lines contain non-compilable ellipsis (...) expressions.

@djubinville
djubinville force-pushed the djubinville/di-hilt-snippets branch 5 times, most recently from f8c3eb1 to b1d9eff Compare October 21, 2026 17:46
@djubinville
djubinville force-pushed the djubinville/di-hilt-snippets branch from b1d9eff to 73d95a0 Compare October 22, 2026 12:38

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant