حاويات حقن التبعية لـ Kotlin: نظرة شاملة ومقارنة
\nحقن التبعية (DI) هو نمط أساسي في التطوير الحديث، يسمح بإنشاء تطبيقات ضعيفة الاقتران، قابلة للاختبار وقابلة للتوسع. في نظام Kotlin البيئي، توجد عدة حاويات DI قوية، لكل منها خصائصه. في هذه المقالة، سنحلل بالتفصيل ثلاثة من أشهر الحلول: Koin و Kodein-DI و Dagger/Hilt. ستتعرف على كيفية عملها، ونقاط قوتها وضعفها، وأي أداة تختار لمشروعك.
\n\nما هي حاوية حقن التبعية؟
\nحاوية DI هي إطار عمل يدير إنشاء ودورة حياة الكائنات (التبعيات) ويقوم تلقائياً بحقنها في الفئات. بدلاً من إنشاء التبعيات يدوياً عبر المُنشئ أو المصنع، تقوم بوصف قواعد البناء في وحدات، وتتولى الحاوية كل المهام الروتينية. هذا مفيد بشكل خاص في المشاريع الكبيرة التي تحتوي على مئات الفئات.
\n\n1. Koin — حاوية DI خفيفة وبسيطة لـ Kotlin
\nKoin هي حاوية DI موجهة بـ DSL، مكتوبة بلغة Kotlin النقية. لا تتطلب توليد كود، أو انعكاس، أو تعليقات توضيحية. يتم جميع الإعدادات من خلال DSL (لغة خاصة بالمجال) سهلة الاستخدام.
\n\nالتثبيت
\n// build.gradle.kts\nimplementation("io.insert-koin:koin-core:3.5.3")\n\nمثال على الاستخدام
\n// تعريف التبعيات\nval appModule = module {\n single { HttpClient() }\n factory { UserRepository(get()) }\n}\n\n// تشغيل Koin\nfun main() {\n startKoin {\n modules(appModule)\n }\n \n // الحصول على التبعية\n val repo: UserRepository by inject()\n}\n\nclass UserRepository(private val client: HttpClient)\n\nالإيجابيات:
\n- \n
- حد أدنى من منحنى التعلم — لا توجد تعليقات توضيحية، ولا توليد كود \n
- سهولة التكامل مع Android (Koin Android) \n
- دعم النطاقات (Scope API) \n
- ترجمة سريعة \n
السلبيات:
\n- \n
- يتم اكتشاف الأخطاء فقط في وقت التشغيل (runtime) \n
- لا يوجد فحص لرسم بياني للتبعيات في وقت الترجمة \n
- أبطأ قليلاً من Dagger في وقت التشغيل بسبب الانعكاس \n
2. Kodein-DI — مرن ومتعدد المنصات
\nKodein-DI هو إطار عمل DI آخر بلغة Kotlin النقية. يقدم إمكانيات متقدمة: دعم المشاريع متعددة المنصات (KMP)، التهيئة المتأخرة، وضع علامات على التبعيات، ومصانع مدمجة.
\n\nمثال على التكوين
\nval di = DI {\n bind<ApiService>() with singleton { RetrofitApiService() }\n bind<Logger>() with provider { ConsoleLogger() }\n bind<UserRepository>() with factory { UserRepositoryImpl(instance()) }\n}\n\n// الاستخدام\nclass MainActivity {\n private val repo: UserRepository by di.instance()\n}\n\nالإيجابيات:
\n- \n
- دعم كامل لـ Kotlin Multiplatform (iOS, JS, JVM) \n
- نظام قوي للعلامات والمعدلات \n
- إمكانية إنشاء حاويات متداخلة \n
- دعم النطاقات وأمان الخيوط \n
السلبيات:
\n- \n
- أقل شهرة من Koin (مجتمع وبرامج تعليمية أقل) \n
- قد تبدو DSL مثقلة للمشاريع البسيطة \n
- أيضاً فحص التبعيات في وقت التشغيل \n
3. Dagger / Hilt — حاوية DI عالية الأداء من Google
\nDagger وطبقة التغليف الخاصة به لنظام Android Hilt هي أطر عمل DI تعتمد على توليد الكود أثناء الترجمة. تستخدم التعليقات التوضيحية (@Inject, @Module, @Component) وتقوم بإنشاء كل كود الربط مسبقاً. هذا يعطي أقصى أداء في وقت التشغيل.
مثال مع Hilt
\n@HiltAndroidApp\nclass MyApplication : Application()\n\n@AndroidEntryPoint\nclass MainActivity : AppCompatActivity() {\n @Inject latein