kmp-di
KMP(Kotlin Multiplatform)環境で、Koinを使ったDependency Injectionの設定や、プラットフォームごとのモジュール定義、手動でのDIパターンなどを活用し、効率的な依存性注入を実現するSkill。
📜 元の英語説明(参考)
Dependency Injection for KMP. Koin multiplatform setup, platform modules, and manual DI patterns.
🇯🇵 日本人クリエイター向け解説
KMP(Kotlin Multiplatform)環境で、Koinを使ったDependency Injectionの設定や、プラットフォームごとのモジュール定義、手動でのDIパターンなどを活用し、効率的な依存性注入を実現するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o kmp-di.zip https://jpskill.com/download/10671.zip && unzip -o kmp-di.zip && rm kmp-di.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10671.zip -OutFile "$d\kmp-di.zip"; Expand-Archive "$d\kmp-di.zip" -DestinationPath $d -Force; ri "$d\kmp-di.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
kmp-di.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
kmp-diフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
KMP 依存性注入
Koin を用いたクロスプラットフォームな依存性注入。
Koin マルチプラットフォーム設定
依存関係
// build.gradle.kts (shared module)
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.insert-koin:koin-core:${koinVersion}")
implementation("io.insert-koin:koin-test:${koinVersion}")
}
}
val androidMain by getting {
dependencies {
implementation("io.insert-koin:koin-android:${koinVersion}")
}
}
}
モジュール定義
// commonMain/kotlin/di/AppModule.kt
val sharedModule = module {
// ViewModels (Android) / ScreenModels (multiplatform)
factory { HomeViewModel(get(), get()) }
factory { DetailViewModel(get()) }
// Use Cases
factory { GetUsersUseCase(get()) }
factory { GetUserDetailUseCase(get()) }
// Repositories
single<UserRepository> { UserRepositoryImpl(get(), get()) }
// Data Sources
single { UserApi(get()) }
single { createDatabase(get()) }
}
プラットフォームモジュール
// androidMain/kotlin/di/PlatformModule.kt
val androidPlatformModule = module {
includes(sharedModule)
// Android-specific dependencies
single { android.content.Context() }
single { PlatformConnectivityMonitor(get()) }
single { PlatformFileService(get()) }
}
// iosMain/kotlin/di/PlatformModule.kt
val iosPlatformModule = module {
includes(sharedModule)
// iOS-specific dependencies
single { PlatformConnectivityMonitor() }
single { PlatformFileService() }
}
Koin の起動
Android
// androidMain/kotlin/MyApp.kt
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@MyApp)
modules(androidPlatformModule)
}
}
}
iOS
// iosMain/kotlin/di/KoinInit.kt
fun initKoin() {
startKoin {
modules(iosPlatformModule)
}
}
// Called from Swift
// KotlinKMMSharedKt.doInitKoin()
Compose Multiplatform
// commonMain/kotlin/Main.kt
fun main() {
startKoin {
modules(sharedModule)
}
App()
}
ViewModel の注入
Android (ViewModel)
// androidMain/kotlin/ui/HomeScreen.kt
@Composable
fun HomeScreen(
viewModel: HomeViewModel = koinViewModel()
) {
val state by viewModel.state.collectAsStateWithLifecycle()
HomeContent(state)
}
iOS (ScreenModel)
// commonMain/kotlin/ui/HomeScreen.kt
@Composable
fun HomeScreen() {
val model = getScreenModel<HomeScreenModel>()
val state by model.state.collectAsState()
HomeContent(state)
}
Repository パターン
Factory vs Single
// ✅ factory - 毎回新しいインスタンスを作成
factory { HomeViewModel(get(), get()) }
// ✅ single - 共有インスタンス
single<UserRepository> { UserRepositoryImpl(get(), get()) }
// ✅ scoped - コンポーネントのライフサイクルに紐づく
scoped(HomeScope.homeScope) { HomeData(get()) }
名前付き依存関係
// ✅ 名前付き依存関係
module {
single(named("default")) { DefaultLogger() }
single(named("analytics")) { AnalyticsLogger() }
factory { MyRepository(logger = get(named("default"))) }
}
手動 DI (代替案)
シンプルな Service Locator
// commonMain/kotlin/di/ServiceLocator.kt
object ServiceLocator {
private val services = mutableMapOf<String, Any>()
fun <T> get(key: String): T {
return services[key] as T
}
fun register(key: String, service: Any) {
services[key] = service
}
fun init() {
register("repository", UserRepositoryImpl())
register("api", UserApi())
}
}
Pure Kotlin DI
// commonMain/kotlin/di/AppContainer.kt
class AppContainer(
private val platformService: PlatformService
) {
val api: UserApi = UserApi()
val database: AppDatabase = createDatabase()
val userRepository: UserRepository by lazy {
UserRepositoryImpl(api, database)
}
val homeViewModel: HomeViewModel by lazy {
HomeViewModel(userRepository, platformService)
}
}
DI を用いたテスト
// commonTest/kotlin/di/TestModule.kt
val testModule = module {
single<MockUserService> { MockUserService() }
single<UserService>(override = true) { get<MockUserService>() }
}
// In tests
@BeforeTest
fun setup() {
startKoin { modules(testModule) }
}
@AfterTest
fun tearDown() {
stopKoin()
}
Remember: DI はテストを簡略化します。モックやフェイクを簡単に注入するために使用してください。
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
KMP Dependency Injection
Cross-platform dependency injection with Koin.
Koin Multiplatform Setup
Dependencies
// build.gradle.kts (shared module)
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.insert-koin:koin-core:${koinVersion}")
implementation("io.insert-koin:koin-test:${koinVersion}")
}
}
val androidMain by getting {
dependencies {
implementation("io.insert-koin:koin-android:${koinVersion}")
}
}
}
Module Definition
// commonMain/kotlin/di/AppModule.kt
val sharedModule = module {
// ViewModels (Android) / ScreenModels (multiplatform)
factory { HomeViewModel(get(), get()) }
factory { DetailViewModel(get()) }
// Use Cases
factory { GetUsersUseCase(get()) }
factory { GetUserDetailUseCase(get()) }
// Repositories
single<UserRepository> { UserRepositoryImpl(get(), get()) }
// Data Sources
single { UserApi(get()) }
single { createDatabase(get()) }
}
Platform Modules
// androidMain/kotlin/di/PlatformModule.kt
val androidPlatformModule = module {
includes(sharedModule)
// Android-specific dependencies
single { android.content.Context() }
single { PlatformConnectivityMonitor(get()) }
single { PlatformFileService(get()) }
}
// iosMain/kotlin/di/PlatformModule.kt
val iosPlatformModule = module {
includes(sharedModule)
// iOS-specific dependencies
single { PlatformConnectivityMonitor() }
single { PlatformFileService() }
}
Koin Start
Android
// androidMain/kotlin/MyApp.kt
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@MyApp)
modules(androidPlatformModule)
}
}
}
iOS
// iosMain/kotlin/di/KoinInit.kt
fun initKoin() {
startKoin {
modules(iosPlatformModule)
}
}
// Called from Swift
// KotlinKMMSharedKt.doInitKoin()
Compose Multiplatform
// commonMain/kotlin/Main.kt
fun main() {
startKoin {
modules(sharedModule)
}
App()
}
ViewModel Injection
Android (ViewModel)
// androidMain/kotlin/ui/HomeScreen.kt
@Composable
fun HomeScreen(
viewModel: HomeViewModel = koinViewModel()
) {
val state by viewModel.state.collectAsStateWithLifecycle()
HomeContent(state)
}
iOS (ScreenModel)
// commonMain/kotlin/ui/HomeScreen.kt
@Composable
fun HomeScreen() {
val model = getScreenModel<HomeScreenModel>()
val state by model.state.collectAsState()
HomeContent(state)
}
Repository Pattern
Factory vs Single
// ✅ factory - creates new instance each time
factory { HomeViewModel(get(), get()) }
// ✅ single - shared instance
single<UserRepository> { UserRepositoryImpl(get(), get()) }
// ✅ scoped - tied to component lifetime
scoped(HomeScope.homeScope) { HomeData(get()) }
Named Dependencies
// ✅ Named dependencies
module {
single(named("default")) { DefaultLogger() }
single(named("analytics")) { AnalyticsLogger() }
factory { MyRepository(logger = get(named("default"))) }
}
Manual DI (Alternative)
Simple Service Locator
// commonMain/kotlin/di/ServiceLocator.kt
object ServiceLocator {
private val services = mutableMapOf<String, Any>()
fun <T> get(key: String): T {
return services[key] as T
}
fun register(key: String, service: Any) {
services[key] = service
}
fun init() {
register("repository", UserRepositoryImpl())
register("api", UserApi())
}
}
Pure Kotlin DI
// commonMain/kotlin/di/AppContainer.kt
class AppContainer(
private val platformService: PlatformService
) {
val api: UserApi = UserApi()
val database: AppDatabase = createDatabase()
val userRepository: UserRepository by lazy {
UserRepositoryImpl(api, database)
}
val homeViewModel: HomeViewModel by lazy {
HomeViewModel(userRepository, platformService)
}
}
Testing with DI
// commonTest/kotlin/di/TestModule.kt
val testModule = module {
single<MockUserService> { MockUserService() }
single<UserService>(override = true) { get<MockUserService>() }
}
// In tests
@BeforeTest
fun setup() {
startKoin { modules(testModule) }
}
@AfterTest
fun tearDown() {
stopKoin()
}
Remember: DI simplifies testing. Use it to inject mocks and fakes easily.