Dependency Injection Mastery
Installation
SKILL.md
Dependency Injection Mastery (依赖注入专精)
Instructions
- 确认问题属于 DI 架构或 Scope 设计
- 依照下方章节顺序套用
- 一次只调整一种注入模式或 module
- 完成后对照 Quick Checklist
When to Use
- Scenario A:新项目 DI 架构创建
- Scenario C:旧项目现代化与模块拆分
- Scenario F:KMP 共用模块的 DI 调整
Example Prompts
- "请参考 Assisted Injection,替 ViewModel 加入动态参数"
- "依照 Custom Hilt Components 创建 User Session Scope"
- "请用 Multi-binding 章节设计插件式支付模块"
Workflow
- 先确认 Assisted Injection 与 Scope 需求
- 再整理 Module Organization 与 Qualifier
- 最后用 Quick Checklist 验收
Practical Notes (2026)
- 多模块采 API/impl 分离,避免跨模块直接依赖实作
- 跨模块导航与 Service 以 interface + EntryPoint 统一
- Scope 设计先画出生命周期,再落地到 Module
Minimal Template
目标:
Scope:
Module 结构:
注入模式:
验收: Quick Checklist
Assisted Injection
当 ViewModel 或 Worker 需要同时接收 DI 的依赖与 Runtime 参数时使用。
ViewModel with SavedStateHandle + Custom Args
@HiltViewModel(assistedFactory = DetailViewModel.Factory::class)
class DetailViewModel @AssistedInject constructor(
@Assisted private val productId: String,
@Assisted savedStateHandle: SavedStateHandle,
private val repository: ProductRepository
) : ViewModel() {
@AssistedFactory
interface Factory {
fun create(productId: String, savedStateHandle: SavedStateHandle): DetailViewModel
}
}
// 在 Compose 中使用
@Composable
fun DetailScreen(productId: String) {
val viewModel = hiltViewModel<DetailViewModel, DetailViewModel.Factory> { factory ->
factory.create(productId, createSavedStateHandle())
}
}
WorkManager with Assisted Injection
@HiltWorker
class SyncWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted params: WorkerParameters,
private val repository: Repository
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
repository.sync()
return Result.success()
}
}
Custom Hilt Components (Scopes)
创建自定义的生命周期范围,例如 User Session。
定义 Custom Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class UserSessionScope
@DefineComponent(parent = SingletonComponent::class)
@UserSessionScope
interface UserSessionComponent
@DefineComponent.Builder
interface UserSessionComponentBuilder {
fun setUser(@BindsInstance user: User): UserSessionComponentBuilder
fun build(): UserSessionComponent
}
管理 Component 生命周期
@EntryPoint
@InstallIn(UserSessionComponent::class)
interface UserSessionEntryPoint {
fun paymentService(): PaymentService
}
@Singleton
class UserSessionManager @Inject constructor(
private val componentBuilder: Provider<UserSessionComponentBuilder>
) {
private var component: UserSessionComponent? = null
fun login(user: User) {
component = componentBuilder.get().setUser(user).build()
}
fun logout() {
component = null
}
fun getPaymentService(): PaymentService {
val currentComponent = checkNotNull(component) { "User not logged in" }
return EntryPoints.get(currentComponent, UserSessionEntryPoint::class.java)
.paymentService()
}
}
Multi-binding (Set & Map)
实作 Plugin 架构,例如多种支付方式。
Set Multibinding
interface PaymentProcessor {
fun process(amount: Double): Result
}
@Module
@InstallIn(SingletonComponent::class)
abstract class PaymentModule {
@Binds
@IntoSet
abstract fun bindCreditCard(impl: CreditCardProcessor): PaymentProcessor
@Binds
@IntoSet
abstract fun bindPayPal(impl: PayPalProcessor): PaymentProcessor
}
// 注入所有实作
class PaymentService @Inject constructor(
private val processors: Set<@JvmSuppressWildcards PaymentProcessor>
) {
fun processAll(amount: Double) {
processors.forEach { it.process(amount) }
}
}
Map Multibinding (with Key)
enum class PaymentType { CREDIT_CARD, PAYPAL, GOOGLE_PAY }
@MapKey
annotation class PaymentTypeKey(val value: PaymentType)
@Module
@InstallIn(SingletonComponent::class)
abstract class PaymentModule {
@Binds
@IntoMap
@PaymentTypeKey(PaymentType.CREDIT_CARD)
abstract fun bindCreditCard(impl: CreditCardProcessor): PaymentProcessor
}
// 按 Key 取得特定实作
class PaymentService @Inject constructor(
private val processors: Map<PaymentType, @JvmSuppressWildcards PaymentProcessor>
) {
fun process(type: PaymentType, amount: Double) {
processors[type]?.process(amount)
}
}
Module Organization
分层架构
di/
├── AppModule.kt # Application-level
├── NetworkModule.kt # Retrofit, OkHttp
├── DatabaseModule.kt # Room
├── RepositoryModule.kt # Repository bindings
└── UseCaseModule.kt # UseCase bindings
Qualifier 使用
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class IoDispatcher
@Module
@InstallIn(SingletonComponent::class)
object DispatcherModule {
@Provides
@IoDispatcher
fun provideIoDispatcher(): CoroutineDispatcher = Dispatchers.IO
}
Quick Checklist
- ViewModel 动态参数使用 Assisted Injection
- 避免在 Module 中使用
@Provides创建复杂逻辑 - Qualifier 用于区分相同类型的不同实例
- 避免 Circular Dependencies
- 测试时使用
@UninstallModules+@TestInstallIn
Related skills
More from fwrite0920/android-skills
crash monitoring
Crashlytics 设置、ANR 分析与结构化日志
9deep performance tuning
Systrace, Memory Analysis, R8 优化与 App Startup 调校
9android skill index
资深 Android 工程师技能导航中心,根据场景推荐适合的技能组合
7coding style conventions
Kotlin 代码规范、Linter 配置与 Code Review 检核标准
7navigation patterns
Deep Links、跨模块导航与复杂 Back Stack 管理
7devops and security
CI/CD 自动化、Gradle 优化与应用程序安全加固
7