Koin — حاوية حقن التبعيات (Dependency Injection) للغة Kotlin

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Koin — حاوية حقن التبعيات (Dependency Injection) للغة Kotlin



في تطوير Kotlin الحديث، تعتبر إدارة التبعيات مهمة أساسية. Koin هي حاوية حقن تبعيات (DI) خفيفة الوزن، مكتوبة بلغة Kotlin، ولا تتطلب توليد كود، أو انعكاس (Reflection)، أو تكوين معقد. على عكس Dagger أو Spring، تستخدم Koin لغة DSL بسيطة وتتكامل بالكامل مع Coroutines و Flow. في هذه الصفحة، سنشرح كيفية تثبيت Koin، تعريف الوحدات، حقن التبعيات، واستخدامها في المشاريع التعليمية.



ما هو حقن التبعيات (Dependency Injection)؟

حقن التبعيات (DI) هو نمط برمجي يتم فيه توفير التبعيات للكائن من الخارج، بدلاً من أن يقوم الكائن بإنشائها بنفسه. هذا يبسط عملية الاختبار، ويجعل الكود أكثر مرونة، ويقلل من الترابط. تقوم Koin بتنفيذ DI من خلال حاوية تدير إنشاء الكائنات ودورة حياتها.



تثبيت Koin

أضف التبعية التالية إلى ملف build.gradle.kts:

// build.gradle.ktsdependencies {    implementation("io.insert-koin:koin-core:3.5.3")    // لنظام Android    implementation("io.insert-koin:koin-android:3.5.3")}


المفاهيم الأساسية في Koin

  • الوحدة (module) — كتلة يتم فيها تعريف التبعيات.
  • التعريف (definition) — طريقة إنشاء الكائن (single, factory, scoped).
  • الحاوية (KoinApplication) — تقوم بتشغيل وإدارة الوحدات.
  • الحقن (inject) — الحصول على التبعية من خلال المفوضين (delegates) أو الدوال.


إنشاء الوحدات وتعريف التبعيات

تستخدم Koin لغة DSL لوصف الوحدات. لنلق نظرة على مثال مع مستودع وخدمة:

// تعريف الواجهة والتنفيذinterface UserRepository {    fun getUser(id: Int): String}

class UserRepositoryImpl : UserRepository { override fun getUser(id: Int) = "User #$id"}

class UserService(private val repository: UserRepository) { fun printUser(id: Int) { println(repository.getUser(id)) }}

// وحدة Koinval appModule = module { // single — ينشئ نسخة واحدة (Singleton) single<UserRepository> { UserRepositoryImpl() } // factory — ينشئ نسخة جديدة مع كل طلب factory { UserService(get()) }}


تشغيل الحاوية

قبل استخدام التبعيات، يجب تشغيل Koin:

import org.koin.core.context.startKoin

fun main() { startKoin { modules(appModule) } // الآن يمكن الحصول على التبعيات val service: UserService by inject() service.printUser(42)}


طرق حقن التبعيات

  • by inject() — الحصول البطيء (موصى به).
  • get() — الحصول الفوري.
  • المنشئ (Constructor) — يقوم Koin تلقائياً بتمرير التبعيات إلى المنشئ.

مثال باستخدام by inject():

class MyActivity : AppCompatActivity() {    // حقن بطيء    private val repository: UserRepository by inject()        override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        // استخدام repository    }}


التبعيات ذات النطاق (Scoped)

في بعض الأحيان، نحتاج إلى إنشاء تبعية تعيش ضمن سياق معين (مثل جلسة المستخدم). لهذا نستخدم scope:

val sessionModule = module {    scope<UserSession> {        scoped { UserSessionManager(get()) }    }}


العمل مع Coroutines

تدعم Koin Coroutines من خلال الوحدة koin-core-coroutines. مثال على الحصول غير المتزامن:

import org.koin.core.component.KoinComponentimport org.koin.core.component.inject                    

توصيات