AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Dagger Hilt Expert

skill-josephsanjaya-skills-dagger-hilt-expert · by JosephSanjaya

Expert guidance for Dagger and Hilt dependency injection in Android. Use when implementing DI, creating modules, configuring scopes, optimizing performance, testing with Hilt, setting up multi-module architecture, using assisted injection, or debugging DI issues. Triggers on "dagger", "hilt", "dependency injection", "@Module", "@Inject", "@Provides", "@Binds", "@Singleton", "@InstallIn", "@HiltAn…

No reviews yet
0 installs
39 views
0.0% view→install

Install

$ agentstack add skill-josephsanjaya-skills-dagger-hilt-expert

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-josephsanjaya-skills-dagger-hilt-expert)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Dagger Hilt Expert? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Dagger & Hilt Expert

Expert guidance for professional Dagger and Hilt dependency injection in Android applications using KSP and modern best practices.

Provide precise, compile-time safe, and high-performance dependency injection advice. When assisting developers with Hilt, prioritize constructor injection, compile-time safety, proper scoping, and optimized test builds.

Core Principles

  1. Constructor Injection First: Prefer @Inject constructor over modules when possible.
  2. @Binds Over @Provides: Use @Binds for interface bindings to optimize class generation and startup.
  3. Narrow Scoping: Only scope when necessary (state, expensive creation, synchronization). Feature-specific dependencies must not be @Singleton.
  4. Single-Purpose Modules: Keep modules focused on one functional area (` for non-critical startup dependencies to prevent app cold-start lag.

Version and Gradle Configuration

Hilt projects should use Kotlin Symbol Processing (KSP) and the latest stable Hilt version (currently 2.59.2).

// build.gradle.kts (Module level)
plugins {
    id("com.google.devtools.ksp")
    id("com.google.dagger.hilt.android")
}

dependencies {
    implementation("com.google.dagger:hilt-android:2.59.2")
    ksp("com.google.dagger:hilt-compiler:2.59.2")
    
    // For tests
    testImplementation("com.google.dagger:hilt-android-testing:2.59.2")
    kspTest("com.google.dagger:hilt-compiler:2.59.2")
    androidTestImplementation("com.google.dagger:hilt-android-testing:2.59.2")
    kspAndroidTest("com.google.dagger:hilt-compiler:2.59.2")
}

Quick Reference

Scope Selection

SingletonComponent (Annotation: @Singleton)
  ↓ (survives config changes)
ActivityRetainedComponent (Annotation: @ActivityRetainedScoped)
  ↓ (per ViewModel)
ViewModelComponent (Annotation: @ViewModelScoped)
  ↓ (per Activity)
ActivityComponent (Annotation: @ActivityScoped)
  ↓ (per Fragment)
FragmentComponent (Annotation: @FragmentScoped)

Use the narrowest scope possible. Do not scope stateless/cheap objects.

Provision Method Selection Decision Tree

Do you own the class constructor?
├─ YES → Is it an interface binding?
│   ├─ YES → Use @Binds on an interface module
│   └─ NO → Use @Inject constructor on the class
└─ NO → Use @Provides on a static object/companion module

Common Patterns

Pattern: Network Module (Static @Provides)

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    @Singleton
    fun provideOkHttp(): OkHttpClient = OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .build()
    
    @Provides
    @Singleton
    fun provideRetrofit(okHttp: OkHttpClient): Retrofit = Retrofit.Builder()
        .client(okHttp)
        .baseUrl("https://api.example.com")
        .addConverterFactory(GsonConverterFactory.create())
        .build()
}

Pattern: Repository Binding (@Binds)

interface UserRepository {
    suspend fun getUser(id: String): User
}

class UserRepositoryImpl @Inject constructor(
    private val api: UserApi,
    private val cache: UserCache
) : UserRepository {
    override suspend fun getUser(id: String): User =
        cache.get(id) ?: api.fetchUser(id).also { cache.put(id, it) }
}

@Module
@InstallIn(SingletonComponent::class)
interface RepositoryModule {
    @Binds
    @Singleton
    fun bindUserRepository(impl: UserRepositoryImpl): UserRepository
}

Pattern: Lazy Initialization

@HiltAndroidApp
class MyApplication : Application() {
    @Inject lateinit var analytics: Lazy
    @Inject lateinit var crashReporter: Lazy
    
    override fun onCreate() {
        super.onCreate()
        crashReporter.get().initialize() // Critical only
        
        // Defer non-critical startup dependency to background thread
        CoroutineScope(Dispatchers.Default).launch {
            analytics.get().initialize()
        }
    }
}

Pattern: Assisted Injection

class DetailViewModel @AssistedInject constructor(
    private val repository: Repository,
    @Assisted private val itemId: String
) : ViewModel() {
    @AssistedFactory
    interface Factory {
        fun create(itemId: String): DetailViewModel
    }
}

// Usage in Fragment
@AndroidEntryPoint
class DetailFragment : Fragment() {
    @Inject lateinit var factory: DetailViewModel.Factory
    
    private val viewModel by lazy {
        factory.create(requireArguments().getString("itemId")!!)
    }
}

Pattern: WorkManager Custom Initialization

WorkManager requires custom initialization with HiltWorkerFactory to inject dependencies into @HiltWorker classes. You MUST implement Configuration.Provider on the Application and disable the default WorkManagerInitializer in the manifest.

@HiltWorker
class SyncWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted params: WorkerParameters,
    private val repository: SyncRepository
) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result = try {
        repository.sync()
        Result.success()
    } catch (e: Exception) {
        Result.retry()
    }
}

Anti-Patterns to Avoid

❌ Monolithic Module

Keep modules single-purpose. Split large modules (e.g., AppModule) into NetworkModule, DatabaseModule, AnalyticsModule.

❌ Feature-Specific Singleton

Do not put feature-specific state (e.g. OnboardingManager) in @Singleton as it causes memory leaks. Use @ActivityScoped or @ViewModelScoped.

❌ Non-Static @Provides

@Module
class NetworkModule { // ❌ Class causes instance overhead
    @Provides fun provideGson(): Gson = Gson()
}

Fix: Use object and @Provides or interface and @Binds.

❌ @Provides for Simple Binding

@Provides fun provideRepo(impl: RepositoryImpl): Repository = impl // ❌ Inefficient

Fix: Use @Binds on an interface module.

Detailed References

For deep dives into architectural setups and patterns, read:

  • [module-organization.md](references/module-organization.md): Single-purpose modules, visibility patterns, multi-module architecture, internal module trick.
  • [scoping-strategies.md](references/scoping-strategies.md): Component hierarchy, scope selection, lifecycle management, memory optimization.
  • [provides-vs-binds.md](references/provides-vs-binds.md): Performance comparison, when to use each, static vs instance methods, qualifiers.
  • [testing-patterns.md](references/testing-patterns.md): @TestInstallIn, @BindValue, @UninstallModules, fakes vs mocks, build optimization.
  • [performance-optimization.md](references/performance-optimization.md): Lazy injection, startup profiling, async initialization, memory management.
  • [assisted-injection.md](references/assisted-injection.md): Runtime parameters, WorkManager, SavedStateHandle, factory patterns.

Scripts

  • analyze_modules.py: Detects monolithic modules, non-static @Provides, and incorrect binding usage.

python scripts/analyze_modules.py

  • generatemoduletemplate.sh: Generates template for provides/binds modules.

./scripts/generate_module_template.sh

  • Developers must always recommend Constructor Injection over modules, unless dependencies are interfaces or external classes.
  • You should never scope stateless dependencies. Explain that scoping only introduces DoubleCheck overhead.
  • WorkManager Hilt integration requires implementing Configuration.Provider on the custom Hilt Application class and disabling the default WorkManager initializer via AndroidManifest.xml (otherwise, a crash will occur).
  • For test environments, you must emphasize the build performance impact of @UninstallModules and recommend @TestInstallIn for global replacements to optimize build times.
  • If the session gets long or slow, suggest /clear or /compact to prevent context decay.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.