0Pricing
Kotlin Academy · บทเรียน

การฉีดการพึ่งพาใน KMP ด้วย Koin

เชื่อมโมดูลที่ใช้ร่วมกันด้วย Koin ในการตั้งค่าแบบหลายแพลตฟอร์ม

การฉีดการพึ่งพาใน KMP ด้วย Koin เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงใช้ DI ใน KMP

การฉีดการพึ่งพาช่วยแยกการสร้างส่วนประกอบออกจากการใช้งาน ใน KMP นั้น Koin เป็นเฟรมเวิร์ก DI ที่เหมาะสม เพราะเป็น Kotlin ล้วนและทำงานใน commonMain ได้โดยไม่ต้องใช้ตัวประมวลผลคำอธิบายประกอบ

// No annotation processing needed — Koin uses lambda DSL
// Add to build.gradle.kts:
// implementation("io.insert-koin:koin-core:3.5.0")
// androidMain: koin-android
// iosMain: no extra dep
fun main() { println("Koin works on all KMP targets") }

DSL ของโมดูล Koin

กำหนดการผูกส่วนประกอบในบล็อก module { } โดยใช้ single, factory หรือ scoped

import org.koin.core.module.dsl.*
import org.koin.dsl.*
val appModule = module {
    single { HttpClient() }               // one instance
    single<UserRepository> { RemoteUserRepository(get()) }
    factory { GetUserUseCase(get()) }      // new instance each time
}

โมดูลที่ใช้ร่วมกันใน commonMain

กำหนดโมดูล Koin ที่ใช้ร่วมกันใน commonMain ส่วนโมดูลของแพลตฟอร์มจะขยายโมดูลนี้ด้วยการผูกส่วนประกอบเฉพาะแพลตฟอร์ม

// commonMain/di/SharedModule.kt
import org.koin.dsl.module
fun sharedModule() = module {
    single<UserRepository> { RemoteUserRepository(get()) }
    single { GetUserUseCase(get()) }
    single { UserViewModel(get()) }
}

โมดูลแพลตฟอร์มใน androidMain

โมดูลแพลตฟอร์มจะจัดเตรียมกลไก HTTP จริง ไดรเวอร์ฐานข้อมูล และซิงเกิลตันเฉพาะ Android

// androidMain/di/AndroidModule.kt
import io.ktor.client.engine.okhttp.*
import org.koin.dsl.module
fun androidModule() = module {
    single { OkHttp.create() }    // Ktor engine
    single { createHttpClient(get()) }
    includes(sharedModule())
}

startKoin ในแอปพลิเคชัน Android

เรียก startKoin { } ใน Application.onCreate ของ Android ใช้ androidContext(this) เพื่อทำให้บริบทพร้อมใช้งาน

// androidMain:
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
// In Application.onCreate():
startKoin {
    androidContext(this@MyApp)
    modules(androidModule())
}

การเริ่มต้น Koin บน iOS

บน iOS ให้เรียก KoinApplication.start() จาก AppDelegate หรือโครงสร้าง App ของ Swift โดยส่งโมดูล Koin ที่ใช้ร่วมกันเข้าไป

// iosMain/KoinInit.kt:
import org.koin.core.context.startKoin
fun initKoin() {
    startKoin {
        modules(iosModule())
    }
}
// Swift: KoinInitKt.doInitKoin() in AppDelegate

การแก้ไขการพึ่งพา

ใน ViewModels หรือกรณีใช้งานของ commonMain ให้ใช้ get() ภายในโมดูล หรือใช้ inject() / getKoin().get() ณ จุดเรียกใช้

import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class UserViewModel : KoinComponent {
    private val getUser: GetUserUseCase by inject()
    fun load(id: String) = runBlocking { getUser(id) }
}

ขอบเขต Koin สำหรับ ViewModels

ใช้ viewModel { } ในโมดูล Android สำหรับ ViewModels ของ Android หรือใช้ factory { } ที่ไม่ขึ้นกับแพลตฟอร์มสำหรับ ViewModels ที่ใช้ร่วมกัน

// androidMain (with koin-android):
import org.koin.androidx.viewmodel.dsl.viewModel
val androidVmModule = module {
    viewModel { UserViewModel(get()) }
}
// In Compose:
// val vm: UserViewModel = koinViewModel()

การทดสอบด้วย Koin

ใช้ startKoin ในการตั้งค่าการทดสอบ พร้อมโมดูลทดสอบที่แทนที่การพึ่งพาจริงด้วยส่วนจำลอง

import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.dsl.module
class UserViewModelTest {
    @BeforeTest fun setup() {
        startKoin { modules(module {
            single<UserRepository> { FakeUserRepository() }
            single { GetUserUseCase(get()) }
        })}
    }
    @AfterTest fun teardown() = stopKoin()
}

Single เทียบกับ Factory และ Scoped

single: อินสแตนซ์เดียวตลอดอายุการทำงานของแอป factory: สร้างอินสแตนซ์ใหม่ทุกครั้งที่เรียก get() scoped: มีอินสแตนซ์เดียวต่อขอบเขต Koin หนึ่งขอบเขต เช่น ขอบเขตหน้าจอ

import org.koin.dsl.module
val lifetimeModule = module {
    single { Database() }           // shared, one instance
    factory { Analytics() }         // new on each get()
    scope<ScreenScope> {
        scoped { ScreenViewModel() } // one per screen lifecycle
    }
}

Koin เทียบกับ DI ด้วยตนเองและ Hilt

Koin: ใช้ได้หลายแพลตฟอร์ม ไม่ใช้ KSP/KAPT และทำ DI ขณะรันไทม์ Hilt: ใช้ได้เฉพาะ Android ทำงานขณะคอมไพล์ และขับเคลื่อนด้วยคำอธิบายประกอบ DI ด้วยตนเอง: ควบคุมได้สูงสุดและไม่มีค่าใช้จ่ายจากเฟรมเวิร์ก โปรเจกต์ KMP ใช้ Koin เพื่อแบ่งปันการทำงาน

fun main() {
    // Koin  : commonMain, runtime, lambda DSL
    // Hilt  : androidMain only, compile-time
    // Manual: no framework, explicit wiring in factory/module files
    println("Choose Koin for KMP; Hilt for Android-only projects")
}

การฉีดแบบขี้เกียจด้วย by inject()

by inject() จะแก้ไขการพึ่งพาเมื่อมีการเข้าถึงครั้งแรก จึงเหมาะกับคลาสที่ใช้งาน KoinComponent

import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class AppService : KoinComponent {
    private val repo: UserRepository by inject()  // resolved on first use
    fun doWork() = println(repo.javaClass.simpleName)
}

ตรวจสอบความเข้าใจ

ขอบเขต Koin ใดสร้างอินสแตนซ์ใหม่ทุกครั้งที่เรียก get()

สรุปทบทวน

Koin ใช้ DSL แบบแลมบ์ดาโดยไม่ต้องประมวลผลคำอธิบายประกอบ จึงเหมาะอย่างยิ่งกับ KMP กำหนดโมดูลที่ใช้ร่วมกันใน commonMain และโมดูลแพลตฟอร์มในชุดซอร์สของแพลตฟอร์ม ใช้ single สำหรับซิงเกิลตัน ใช้ factory สำหรับอินสแตนซ์ใหม่ และใช้ by inject() สำหรับการแก้ไขการพึ่งพาแบบขี้เกียจ

คำถามที่พบบ่อย

บทเรียน “การฉีดการพึ่งพาใน KMP ด้วย Koin” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การฉีดการพึ่งพาใน KMP ด้วย Koin” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การฉีดการพึ่งพาใน KMP ด้วย Koin”

เชื่อมโมดูลที่ใช้ร่วมกันด้วย Koin ในการตั้งค่าแบบหลายแพลตฟอร์ม คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การฉีดการพึ่งพาใน KMP ด้วย Koin” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โครงสร้างโปรเจกต์ KMP: commonMain, androidMain, iosMain
  2. กลไก expect/actual สำหรับ API ของแพลตฟอร์ม
  3. การแชร์ชั้น Repository และ Use Case
  4. การฉีดการพึ่งพาใน KMP ด้วย Koin
← กลับไปที่ Kotlin Academy