خنجر 2 هو الابتدائية (الجزء 2)

الجزء السابق

محتوى

  1. تنفيذ الأساليب والحقول
  2. تأخر التهيئة في الخنجر
  3. وحدات خنجر. عندما لا يفهمك الخنجر
  4. مجردة اسمه. حالات متعددة من نفس النوع

تنفيذ الأساليب والحقول

يصف الجزء الأول طريقة لتطبيق التبعية على مستوى المُنشئ. بالإضافة إلى ذلك ، يمكن للخنجر تطبيق التبعيات للحقول والأساليب. ولكن يجب استخدام هذه التطبيقات عند الضرورة القصوى.

مثال على طريقة التنفيذ:

class Car @Inject constructor(private var engine: Engine){ var key: Key? = null @Inject set } class Key @Inject constructor() 

في المثال أعلاه ، يتم تطبيق تبعية الطريقة المحددة لحقل المفتاح

يتم تنفيذ الحقول على ثلاث مراحل:

  1. إضافة طريقة تضمين لمصنع مجردة
  2. تحديد الحقول ليتم تنفيذها
  3. استخدم أساليب التنفيذ في تطبيق خنجر فئة مجردة لتنفيذ التبعيات

من الواضح أنه سيكون من الأسهل فهم هذا الأمر بالترتيب

1. في فصلنا التجريدي ، أضف طريقة تنفيذ لـ MainActivity

 @Component interface DaggerComponent { fun getCar(): Car fun getEngine(): Engine fun getFuel(): Fuel fun inject(act: MainActivity) } 

2. تحديد المجالات التي ينبغي تنفيذها في MainActivity. يجب أن تكون الحقول التي تم حقنها متأخرة var وأن تكون مرئية للجميع (عام)

 @Injected lateinit var car: Car 

3. نحن نسمي الطريقة المضافة inject () للفئة المجردة لتنفيذ مجالات النشاط.

في النهاية ، ستبدو فئة MainActivity الخاصة بنا بمثابة أثر. الطريقة:

 class MainActivity : AppCompatActivity() { @Inject lateinit var car: Car override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerDaggerComponent.create().inject(this) } } 

تأخر التهيئة في الخنجر

كما تعلم ، عند بدء تشغيل التطبيق ، ليست هناك حاجة دائمًا إلى مثيلات جميع الفئات. هذا يسرع الإطلاق الأول وأكثر من ذلك. هناك نوعان من تهيئة الكائنات المضمّنة في الخنجر: Provider <> و Lazy <>

موفر - يحدث التهيئة عند الاستدعاء الأول للكائن ومع كل مكالمة ، سيتم إرجاع مثيل جديد للكائن
كسول - يحدث التهيئة عند الاستدعاء الأول ، ثم يتم إرجاع الحالات المخزنة مؤقتًا مسبقًا

لاستخدام هذه الأنواع من التهيئة ، من الضروري "التفاف" الكائنات التي تمت تهيئتها في النموذج المطلوب.

مثال على استخدام الموفر:

 class Engine @Inject constructor(private var fuel: Fuel){ fun start(){ if(fuel!=null){ print("Started!") }else{ print("No more fuel!") } } } class Car @Inject constructor(private var engine: Provider<Engine>){ var key: Key? = null @Inject set fun startCar(){ engine.get().start() } } class Key @Inject constructor() 

في كل مرة تسمى طريقة get () ، نحصل على مثيل جديد للكائن المرغوب.

مثال على استخدام Lazy:

 class Fuel @Inject constructor() { val fuelType = if(BuildConfig.DEBUG){ "benzine" }else{ "diesel" } } class Engine @Inject constructor(private var fuel: Lazy<Fuel>){ fun start(){ if(fuel!=null){ print("Started with ${fuel.get().fuelType}") }else{ print("No more fuel!") } } } 

في كل مرة تسمى طريقة get () ، نحصل على نفس المثيل.

تحذير! عند إضافة طريقة get () لطريقة العرض Lazy في Android Studio ، قد يكون تحتها خط باللون الأحمر منذ ذلك الحين Kotlin لديها فئة كسول الخاصة بها. لذلك نحن استيراد الطبقة خنجر

 import dagger.Lazy 

وحدات خنجر. عندما لا يفهمك الخنجر

هناك أوقات لا يفهم فيها خنجر نواياك. على سبيل المثال ، فئة السيارات لدينا تحتوي على حقل من النوع (واجهة) Driver ، والذي ورثته فئة Ivanov

عندما تحاول تنفيذ حقل بنوع واجهة ، تظهر لك رسالة الخطأ "لا يمكن توفيرها دون استخدام أساليب @ المشروح".

لحل هذه المشكلة ، يقترح الخنجر استخدام الوحدات النمطية. تزود الوحدات الخنجر بمعلومات إضافية لا يمكنه الحصول عليها بمفرده. كوحدات ، يمكنك استخدام واجهات أو كائنات (كائن).

لحل المشكلة أعلاه ، قم بإنشاء وحدة نمطية:

 @Module interface DaggerModul { @Binds fun bindDriver(driver: Ivanov): Driver } class Ivanov @Inject constructor(): Driver 

في طريقة bindDriver ، سنشرح كيف نبدأ في تهيئة الواجهة.

في المكون أيضًا ، تحتاج إلى سرد جميع وحدات الخنجر الحالية

 @Component(modules = [DaggerModul::class]) interface DaggerComponent { … } 

لنفترض بالنسبة لفئتنا Engine استخدام حقل أسطوانة مكتبة الجهة الخارجية (الواجهة). كيفية وصف مثل هذا الحقل للخنجر إذا لم يكن من الواضح أي فئة سيتم تهيئتها في وقت التشغيل؟

حتى الآن ، استخدمنا التعليقات التوضيحية لشرح كيف ينبغي حقن التبعيات. ماذا لو كنت لا تعرف كيفية إنشاء فصول من المكتبات الأجنبية ، على سبيل المثال؟

يوفر التعليق التوضيحي وصفًا لتلك الحالات عندما تحتاج إلى وصف صريح لمثيل الفئة التي ترغب في تهيئتها.

 @Module object DaggerModuleObject { @Provides @JvmStatic fun getBoschCylinder(): Cylinder = BoschCylinder() } 

وبالتالي ، فإننا نخبر الخنجر أنه عند تهيئة حقل الأسطوانة ، نحتاج إلى مثيل لفئة BoschCylinder.

مجردة اسمه . حالات متعددة من نفس النوع

هناك أوقات تحتاج فيها إلى إنشاء مثيلات من نفس الفئة بإعدادات مختلفة. في مثالنا ، هذه ألوان مختلفة على الجسم والأبواب.

عند محاولة بناء مشروع مع تتبع. سوف تحصل الوحدة على الخطأ "(صفنا) اللون مرتبط عدة مرات"

 @Provides @JvmStatic fun getColorRed():Color = Color("red") @Provides @JvmStatic fun getColorBlue():Color = Color("blue") 

لحل مثل هذه الحالات ، يتم استخدام الشرح المسماة . بادئ ذي بدء ، في الوحدة النمطية ، سننشئ 3 طرق جديدة للتهيئة في الخنجر

 @JvmStatic @Provides fun getColor(): Color = Color("") @Provides @Named("blueColor") @JvmStatic fun getColorBlue(): Color{ return Color("blue") } @JvmStatic @Named("redColor") @Provides fun getColorRed(): Color = Color("red") 

الطريقة الأولى هي الطريقة الافتراضية ، وبدون ذلك سيقسم الخنجر عن غياب الفئة "لا يمكن توفيره بدون مُنشئ Inject أو طريقة موضحة Provides"

إرجاع طريقتين التالية مثيلات من نفس الفئة. يبقى لإضافة تطبيق هذه الفئة في الأماكن الصحيحة والاتصال مع الشرح المسماة

 class Door @Inject constructor() { @Named("blueColor") @Inject lateinit var color:Color } class Car @Inject constructor(private var engine: Provider<Engine>, private var door: Door, var driver: Driver){ var key: Key? = null @Inject set @Inject @Named("redColor") lateinit var color: Color fun startCar(){ engine.get().start() } } class Key @Inject constructor() 

شفرة المصدر

Source: https://habr.com/ru/post/ar466769/


All Articles