آموزش استفاده از Dagger 2 در اندروید

آموزش اندروید تزریق وابستگی با استفاده از دگر 2 android tutorial dagger 2 dependency injection java اندروید اینجکشن

سطح آموزش:  #پیشرفته

مقدمه

پیش نیاز این آموزش آشنایی با dependency injection یا تزریق وابستگی هست.

برای یاد گرفتن بحث تزریق وابستگی باید توجه کنیم که یاد گرفتنِ اون به معنی توانایی استفاده توی پروژه‌ها نیست. وقتی بفهمیم چطور میتونیم از dagger 2 برای تزریق وابستگی در پروژه اندروید استفاده کنیم مرحله اول یعنی کسب دانش رو با موفقیت طی کردیم. ولی برای اینکه بتونیم به طور عملی از این دانش استفاده کنیم نیاز داریم که مهارت استفاده از دانش رو هم داشته باشیم و مهارت جز با تمرین به دست نمیاد. بنابراین بعد از این آموزش سعی کنید dependency injection رو در تمام پروژه‌هاتون استفاده کنید.

اضافه کردن کتابخانه

به dependencies در gradlتون خط‌های زیر رو اضافه کنید.

 

annotationها در  Dagger 2

تو آموزش قبلی یاد گرفتیم که خوب نیست کلاس‌ها به همدیگه وابسته باشن و بهتره ما این وابستگی رو از داخل کدِ کلاس خارج کنیم و در عوض از خارج به کلاس تزریقش کنیم. یعنی مثلا توی مثال Contact و User در آموزش قبلی، به جای اینکه برای هر User یک Contact بسازیم، contact رو به user تزریق کنیم.

بدون dagger ما برای تزریق یک شی از contact رو در زمان ساخت برای user میفرستادیم تا داخل کلاس user مجبور به ساخت نشیم. اما با dagger ما میتونیم صرفا بیان کنیم که کلاس user نیاز به یک contact داره و بعد از بیان این وابستگی عمل تزریق (inject) رو به عهده Dagger بذاریم. اما به هرحال ما باید یک جایی (module) شیء contactـی برای استفاده در user فراهم (provide) کنیم و در نهایت در جایی (component) این رو به هم ارتباط بدیم.

 

برای تمام این کارها dagger 2 از چند annotation بخصوص استفاده میکنه:

@Module: برای کلاس‌هایی که متدهاشون وابستگی‌های ما رو تامین (provide) میکنن.

@Provides: برای متدهاییه که داخل کلاس‌های Module هستن.

@inject: برای درخواست وابستگی. هرجا وابستگی داشته باشیم با این annotation اعلام میکنیم.

@Component: یک interface هست که بین moduleها (یعنی کلاس‌های تامین کننده وابستگی) و injectها (یعنی جاهایی که وابستگی داریم) ارتباط بر قرار میکنن.

کارکردن با Dagger 2

برای پیاده‌سازی dagger ما مراحل زیر رو طی میکنیم:

  1. اشیاء وابسته و وابستگی‌شون رو شناسایی میکنیم.
  2. کلاس‌های @Module رو همراه با متدهای @Provides می‌سازیم که این وابستگی رو فراهم کنیم.
  3. با استفاده از @inject درخواست وابستگی میدیم.
  4. interfaceـی با @component می‌سازیم که بین وابستگی‌ها و فراهم‌کننده‌های این وابستگی ارتباط برقرار کنیم.
  5. یک شیء از اینترفیسمون که @component داره می‌سازیم تا با استفاده از اون شیء وابستگی‌دار و وابستگی‌هاش رو بسازیم.

پیاده‌سازی Dagger 2 در یک پروژه واقعی

میخوایم Dependency Injection رو با استفاده از Dagger 2 برای مثالِ Contact و User که در آموزش قبل داشتیم در اندروید استودیو پیاده‌سازی کنیم.

گام اول: شناسایی وابستگی

اول به سراغ کلاس Contact میریم و به شکل زیر پیاده‌سازیش میکنیم:

کلاس Contact یک فیلد String برای ایمیل داره. متد deleteMail مقدار ایمیل رو null قرار میده و توی constructor هم مقدار “No Contact” رو براش قرار میدیم.

حالا کلاس User رو میسازیم:

کلاس User یک Contact داره که توی constructor مقداردهی‌ش میکنه. بقیه متدها نکته خاصی ندارن فقط اگر از همین کدها استفاده می‌کنید توجه کنید که در آینده (گام سوم) یک تغییر جزئی در کدهای این کلاس خواهیم داد.

گام دوم: ساخت module و providerها

گفتیم کار module در dagger 2 فراهم کردن (provide) هست. کلاس User وابستگی‌ای داره که نیاز به فراهم شدن داره بنابراین براش یک module مینویسیم:

توضیح کد:
  • @Module در ابتدای کلاس: با این annotation اعلام میکنیم که این کلاس یک module هست. بنابراین شامل متدهایی خواهد بود که وابستگی‌های ما رو برامون فراهم میکنن.
  • @Provides در بالای هر متد: به این شکل به dagger اعلام میکنیم که این متد یک فراهم کننده یا provider هست. یعنی اگر جایی احتیاج به Contact داشتی (یعنی با @inject وابستگی تعریف کرده بودیم) بیا و از این provider استفاده کن.
  • @Singleton در بالای هر متد: قبلا مفصل راجع به سینگلتون صبحت کردیم. با این annotation به dagger میگیم که میخوایم یک نسخه از این شیء در برنامه وجود داشته باشه.

گام سوم: مشخص کردن وابستگی‌ها

گفتیم که inject برای درخواست وابستگی هست. با اضافه کردن @inject به constructor کلاس User وابستگی این کلاس به contact رو مشخص می‌کنیم. یعنی اعلام میکنیم که ما توی این constructor یک وابستگی داریم (که همون Contact هست).

گام چهارم: ارتباط بین وابسته‌ها و فراهم‌کننده‌ها با component

یک اینترفیس به اسم UserComponent به شکل زیر میسازیم:

همونطور که گفتم کار component ارتباط دادن وابستگی‌ها و فراهم کننده‌هاست هست. برای این کار نیاز داریم فراهم کننده‌ها رو به component بشناسونیم.

و از اونجایی که فراهم کننده‌ها در moduleها هستن به شکل زیر اعلام میکنیم که این component چه moduleهایی رو شامل میشه:

اگر بیش از یک module داشتیم به شکل زیر عمل میکردیم:

توی کامپوننت یک متد برای هر شیء‌ای که نیاز داریم میسازیم. توی این مثال ما فقط به User احتیاج داریم. برای همین یک متد برای گرفتن User می‌سازیم. زیبایی کار اینجاست که userـی که توسط این متد برامون فراهم میشه تمام وابستگی‌هاش به طور خودکار تامین خواهد شد.

ما درخواست یک user میدیم و Dagger هروقت که نیاز شد با استفاده از annotationهایی که گذاشتیم میره و contact رو برای user ما فراهم میکنه.

گام پنجم: استفاده از شیء وابستگی دارمون!

دیگه میتونیم با نمونه گیری از component و استفاده از متدهاش از شیءای که وابستگی داره نمونه بسازیم و استفاده کنیم. این کارو توی MainActivity انجام میدم و ایمیل رو بصورت toast نمایش میدم:

توجه کنید که DaggerUserComponent رو کتابخونه Dagger برامون میسازه و برای اینکه بتونه اون رو بسازه نیاز داریم یکبار Make Project کنیم. برای اینکار توی android studio کافیه ctrl+f9 رو بزنید.

این آموزش اولین پست از یک مجموعه بود که در اون‌ها Dagger رو آموزش میدم. بخش بعدی دوم آموزش Dagger رو از اینجا می‌تونید دنبال کنید.

منابع

در نهایت من سعی کردم جایی که توی این مجموعه پست میتونستم به تمام نکات مربوط به dependency injection بپردازم و کامل بررسی کنم. اما مطمئنم برای خیلی‌ها هنوز مطلب کامل جا نیفتاده. بهترین کار بعد از تمرین زیاد نگاه کردن به مقالات آموزشی دیگه توی همین زمینه‌ست. چرا که هر مقاله از یک منظر به موضوع نگاه کرده و در کل خوندن چند مقاله متفاوت باعث میشه یک دید جامع نسبت به موضوع پیدا کنید.

ضمن اینکه خودِ من هم برای نوشتن این مجموعه پست از این لینک‌ها استفاده کرده‌ام: + + + + + +

در نهایت جامع‌ترین چیزی که در خصوص dagger میتونید بخونید user guideخودشه که از این لینک میتونید مطالعه‌ش کنید.

 

15 دیدگاه برای “آموزش استفاده از Dagger 2 در اندروید

  1. با سلام و تشکر از مطلب مفیدتون.یه سوال برام پیش اومده.واسه تزریق وابستگی حتما باید inject@ رو به کانستراکتر تزریق کرد.
    من تو اپلیکیشن م به یه مشکلی خوردم.
    یه فرگمنت دارم که وابستگی به یه کلاس آداپتر داره.میشه اینو با dagger مرتفع کنم وابستگی هاشو؟
    البته میخواستم این کارو کنم ولی بهم اجازه نداد کانستراکتور دیگه ای تو فرگمنتم بسازم که بتونم وابستگی رو بهش inject کنم.
    به طور کلی توضیح میدین وقتی کلاس های وابسته، تهیه کننده مون از جنس فرگمنت، اکتیویتی یا آداپتر باشن چطوری میشه وابستگی ها رو براشون تامین کرد؟

  2. dagger-2 باعث ایجاد پیچیدگی در کد میشه و از همه مهم تر اگر تیمی روی پروژه کار بشه باید همه تیم یا dagger-2 رو یاد بگیرن و یا هر کسی هرجور بلده کد بزنه .

    بهترین روش روش استاندارد تزریق وابستگی هست .

    1. ابتدا توی خط ۱۰ یک کامپوننت و ماژولش رو می‌سازیم. توی خط بعدی هم با صدا کردن provideUser یک instance از user میگیریم که بتونیم استفاده کنیم. البته ادامه پست‌ها رو ببینید یاد میگیریم که دیگه نیازی نیست این کارها رو دستی انجام بدیم و کاری می‌کنیم که هم ماژول خودش اضافه میشه و هم با annotation ها مقدار user رو inject می‌کنیم.

  3. سلام طاهر جان
    یه سوال داشتم توی ساخت ادپتر برای یک ریسایکلرویو هم وقتی یک لیست از یک مدل رو بهش پاس میدیم هم باید dependency injection ساتفاده کنیم؟
    یعنی هر کلاسی که قبلا بهش با استفاده از کانستراکتور یک کلاس یا لیستی از یک کلاس دیگه رو بهش پاس میدادیم باید dependency injection استفاده کرد؟
    ممنون

  4. سلام شب بخیر من میخواستم realm رو با dagger 2 از وابستگی خارج کنم و بتونم هرجا خواست تزریق کنم و استفاده کنم میتونید راه نمیی کنید با تشکر .

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *