Dagger hilt nədir? Hilt ilə Android 1-ci hissə

Novruz Jafarov
5 min readOct 16, 2022

--

Dagger hilt — Manual dependency injection zamanı yazdığımız boilerplate (səliqəsiz, qarışıq) kodları azaltmağa kömək edən dependency injection kitabxanasıdır. Dependency injection nədir və nə üçün istifadə olunur sualına əvvəlki məqalədə cavab tapa bilərsiniz. Məqalənin linkini aşağıda qeyd etmişəm. Manual dependency injection zamanı bütün sinifləri və bağımlılıqları əl ilə təyin etmək, onlardan təkrar istifadə etmək üçün isə konteyner siniflərdən istifadə etməyə məcbur olurduq. Hilt bizə, android siniflərimizə konteynerlər təyin etmək və onların yaşam dövrlərini (lifecycle) avtomatik şəkildə idarə etmək üçün bir standart təqdim edir.

Hilt, məşhur Dagger 2 kitabxanası üzərinə inşa edilmişdir, annotasiyalar üzərinə qurulmuşdur və Dagger 2 dən fərqli olaraq tətbiqi və istifadəsi daha asan, oxunaqlı və az kod yazmaqla daha effektiv nəticələri bizə verən bir kitabxanadır.

Bağımlılıqların əlavə olunması

İlk öncə proyektimizin root build.gradle faylına aşağıdakı kodları əlavə edirik:

Sonra isə bağımlılıqları proyektimizin app/build.gradle faylına əlavə edirik. Dagger hilt Java 8 — dən istifadə etdiyi üçün əlavə olaraq compileOptions-a aşağıda gördüyümüz kod sətirlərinidə əlavə etməliyik:

Bütün bu kod sətirlərini əlavə etdikən sonra gradle sinxronizasiya edirik və proyektimizdə artıq dagger hilt istifadə edə bilərik.

Hilt Application sinifi

Dagger Hilt istifadə edən bütün proqramlar, mütləq @HiltAndroidApp annotatsiyası tətbiq edilmiş bir Application sinifinə sahib olmalıdır. Bizdə həmin sinifi proyektimizdə yaradaq. Əlavə olaraq AndroidManifest faylında öz App sinifimizi təyin etməliyik:

Bu yaradılan hilt komponenti Application obyektinin yaşam dövrünə əlavə edilir və ona bağımlılıqlar təyin etməyimizə icazə verir. Həmçinin bu komponent əsas (parent) komponent sayılır və digər komponentlərin təyin etdiyi bağımlılıqları istifadəsi əlçatandır.

Bağımlılıqların Android siniflərinə injekt olunması

Hilt Application sinifimizi təyin etdikdən sonra Hilt bizə, @AndroidEntryPoint annotasiyası altında digər android siniflərinə bağımlılıqları tətbiq etməyimizə icazə verir. Məsələn:

Hilt bu android siniflərinə dəstək verir:

  • Application (@HiltAndroidApp vasitəsi ilə)
  • ViewModel (@HiltViewModel vasitəsi ilə)
  • Activity
  • Fragment
  • View
  • Service
  • BrodcastReceiver

Əgər bir android sinifini @AndroidEntryPoint annotasiyası ilə işarələsək, onu istifadə edən və ya saxlayan (depending) digər android sinifindədə bu annotasiya ilə işararələmək vacibdir. Məsələn: Bir fragment bu annotasiyanı tətbiq edirsə, onu özündə saxlayan Activity də mütləq bu annotasiyanı tətbiq etməlidir.

Field Injection

@AndroidEntryPoint annotasiyasını tətbiq etdiyimiz sinifimizdə @Inject annotasiyası ilə field injection tətbiq edə bilərik. Inject etmək istədiyimiz dəyişkən private olmamalıdır. Bu şəkildə proqramı işə salsaq Dagger bizə xata olduğunu və injekt etməyə çalışdığımız obyekti heç bir yerdə təyin etmədiyimizi qeyd edəcək:

Hilt bağlılıqlarını təyin etmək (Hilt bindings)

Field injection etməyə çalışdığımız anda, Hiltin həmin komponentdən lazım olan bağımlılıqları necə əldə edəcəyini bilməsi lazımdır. Binding — bir obyekti bağımlılıq olaraq saxlamaq üçün lazım olan məlumatlardan ibarətdir.

Constructor Injection (Konstruktor injeksiyası). Konstruktora @Inject annotasiyası tətbiq etməklə bu konstruktorun parametrləri həmin sinifin bağımlılıqlarını təyin etmiş olur. Nümunədə bir TestApi interfeysimiz var və onu parametr olaraq Repository sinifimizə veririk. Bu vəziyyətdə Hilt Repository sinifimizi necə təyin etməli olduğunu da bilməlidir. Belə olan halda proqramımızı işə salsaq yenə eyni xətanı alacıyıq, çünki Hilt -in bu siniflərimizi necə təyin edəcəyimizdən xəbəri yoxdur.

Modullar

Bəzi hallarda, bir obyektin bir konstruktor tərəfindən injekt edilməsi mümkünsüz ola bilər. Məsələn bir interface istifadəsi zamanı konstruktor injekt tətbiq edilə bilməz. Həmçinin özümüzün yazmadığı bir obyekti, məsələn, hər-hansısa bir kitabaxanada olan bir sinifin obyektine konstruktor injeksiyası tətbiq edə bilmərik. Bu hallarda Hilt modullarından istifadə etməliyik.

Hilt Module — @Module annotasiyası tətbiq edilmiş bir sinifdir.Dagger modullarında olduğu kimi Hilt -ə müəyyən obyektlərin bağımlılıqlarını necə əldə edəcəyini bildirmək üçün istifadə edilir. Hilt modullarında, hansı android siniflərinə injeksiya edəcəyəmizi @InstallIn annotasiyası ilə bildirməliyik.

@Provides ilə bağımlılıqları təyin etmək

Bir obyektə kontruktor injekt tətbiq edə bilmədiyimiz tək yer interfeyslər deyil. Əgər xarici bir kitabxana istifadə ediriksə (Məs: Retrofit, Room, OkHttpClient) , bu hallarda da konstruktor injeksiyası mümkün deyil. Belə hallarda nümunədəki kimi öz NetworkModule sinifimizi yaradırıq və bağımlılıqlarımızı @Provides annotasiyası ilə təyin etmiş oluruq. @Singleton annotasiyası isə, təyin edilən sinifdən bir dəfə obyekt yaradılacağı anlamına gəlir (Singleton Pattern).

@InstallIn — içərisinə parametr olaraq SingletonComponent vermişik. Bu o deməkdir ki, təyin etdiyimiz bağımlılıqlar App səviyəssində hər yeri əhatə edir. Əgər onun yerinə ActivityComponent istifadə etmiş olsaydıq, proqram daxilində olan bütün activity-lər çərçivəsində istifadə oluna bilərdi:

Nümunədə gördüyümüz kimi @Provides ilə bağımlılıqlarımızı təyin edirik və bəzi metodlara parametr olaraq veririk. Bu halda Dagger özü həmin obyekti təyin edir və parametr olaraq verir. Məsələn, retrofit obyektimizi yaratmışıq və testApi obyektimizi yaratmaq üçün yazdığımız funksiyaya parametr olaraq veririk. Bu halda Dagger özü parametrin yuxarıda təyin etdiyimiz retrofit obyektindən gəldiyini təyin edir

Beləliklə Dagger Hilt ilə sadə Dependency İnjection strukturu qurmuş olduq. Məqalənin ikinci hissəsində @Binds annotasiyası haqqında, eyni tipdə olan obyektləri tanımlama, Komponentlər və Scope-lar haqqında danışacağıq.

Mənbə: developer.android.com

--

--