Android Uygulamasında Hilt Nasıl Uygulanır?

giriiş
3 tip bağımlılık enjeksiyonu vardır:
- Manuel bağımlılık enjeksiyonu – Yapıcı parametreleri aracılığıyla bağımlılık enjekte edin
- Servis bulucu – Bağımlılıkları tutan singleton kapsayıcı
- Bağımlılık ekleme kitaplığı – Kitaplık/çerçeve gibi kabza/hançer ve Koin, daha az kodla manuel bağımlılık enjeksiyonu ile benzer işlevsellik sağlar.
Bağımlılık ekleme kitaplığının kullanımı zordur. Hilt/Dagger ve Koin’i ilk duyduğumda, ne oldukları hakkında hiçbir fikrim yoktu. Bu yüzden belgelerini ve öğreticilerini okudum, anlayışımı daha da kötüleştiriyor!
Benim ilk deneyimim Koin’di. Android Kotlin Developer Nodegree programı. Kod zaten sağlandı ve %100 anlamadan kullandım.
Koin’i anlamaya çalışmak yerine, Dagger’ın üzerine inşa edilmiş ve kullanıcı dostu olması gereken Hilt ile karşılaştım. Ben de bunu denedim ve bu yararlı ve basit resmi öğreticiyi buldum – Android uygulamanızda Hilt’i kullanma. Bu öğretici, hizmet bulucuyu Hilt bağımlılık enjeksiyonuna dönüştürmeyi adım adım gösterir.
Bu yüzden Hilt’i uygulama adımlarını belgelemenin benim için iyi bir fikir olabileceğini düşünüyorum. Bu makale, bu Hilt eğitimindeki adımları özetlemektedir.
1. Hilt Bağımlılıklarını Ayarlayın
İçinde build.gradle
(proje seviyesi), Hilt Android gradle eklentisini ekleyin.
buildscript {
...
}
dependencies {
...
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.40'
}
}
İçinde build.gradle
(uygulama düzeyi), ekle kotlin-kapt
ve dagger.hilt.android.plugin
.
plugins {
...
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
Hilt uygulama bağımlılıkları ekleyin.
dependencies {
...
implementation 'com.google.dagger:hilt-android:2.40'
kapt 'com.google.dagger:hilt-android-compiler:2.40'
...
}
2. Ekle @HiltAndroidApp
uygulama sınıfınızda
Bir uygulama sınıfınız yoksa, bir tane oluşturmanız gerekir.
@HiltAndroidApp
class LogApplication : Application() {
...
}
Ayrıca güncellemeniz gerekiyor android:name
içinde AndroidManifest.xml
.
<manifest>
<application
android:name=".LogApplication"
...
</application>
</manifest>
3. Ekle @AndroidEntryPoint
aktivitenizde ve parçanızda
Bağımlılıklarınızı aktiviteye enjekte etmek istiyorsanız, sadece eklemeniz gerekir. @AndroidEntryPoint
aktivite sınıfınızda. Ancak, bağımlılıklarınızı parça halinde enjekte etmek istiyorsanız, eklemeniz gerekir. @AndroidEntryPoint
hem parçada hem de parçayı barındıran aktivitede.
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
...
}
@AndroidEntryPoint
class LogsFragment : Fragment() {
...
}
4. Ekle @Inject lateinit var
alan enjeksiyonu yapmak
Kullanmak @Inject lateinit var
Hilt, istediğiniz sınıf alanında sizin için örneği otomatik olarak oluşturur. Bu örnekte, Hilt otomatik olarak logger
parça ilk eklendikten sonra sizin için örnek (yani onAttach()
denir)
class LogsFragment : Fragment() {
...
@Inject lateinit var dateFormatter: DateFormatter
@Inject lateinit var logger: LoggerDataSource
...
}
5. Ekle @Inject constructor()
Hilt’e bağımlılıkların nasıl sağlanacağını söylemek
Hilt nasıl oluşturulacağını bilmiyor. DateFomatter
ve LoggerDataSource
. Bunu yapmak için eklemeniz gerekir @Inject constructor()
sınıflara girer.
class DateFormatter @Inject constructor() {
...
}
class LoggerLocalDataSource @Inject constructor(private val logDao: LogDao) {
...
}
eksik bilgi nedeniyle LogDao
Hilt hala yapıcının nasıl enjekte edileceğini bilmiyor LoggerLocalDataSource
. Böylece, ihtiyacımız var kabza modülünü oluştur nasıl olduğunu anlatmak LogDao
oluşturulabilir.
6 Ekle @Singleton
örneği tüm uygulamaya kapsamak için
@Singleton
class LoggerLocalDataSource @Inject constructor(private val logDao: LogDao) : LoggerDataSource {
...
}
Bu aynı anlama gelir LoggerLocalDataSource
tüm uygulama için kullanılacaktır. farklı var bileşen kapsamları gibi @ActivityScoped
, FragmentScoped
ve @ViewModelScoped
.
7. Ekle @Module
ve @InstallIn
Hilt Modülleri oluşturmak için
Hilt’in yapıcı olarak bağımlılıkları nasıl enjekte edeceğini bilmediği bu sınıflar için Hilt Modülünü oluşturmanız gerekir.
@InstallIn(SingletonComponent::class)
@Module
object DatabaseModule {
...
}
@InstallIn
bileşen kapsamlarıyla ilgili olan bu modülün hangi Hilt bileşenine kurulacağını belirtin.
8. Örnekleri şu şekilde enjekte edin: @Provides
Onlar 2kişi @Provides
. İlk @Provides
nasıl bilgi sağlar LogDao
oluşturulabilir. Çünkü buna bağlı AppDatabase
ikinci @Provides
nasıl bilgi sağlar AppDatabase
oluşturulabilir.
@InstallIn(SingletonComponent::class)
@Module
object DatabaseModule {
@Provides
fun provideLogDao(database: AppDatabase): LogDao {
return database.logDao()
}
@Provides
fun provideDatabase(@ApplicationContext appContext: Context): AppDatabase {
return Room.databaseBuilder(
appContext,
AppDatabase::class.java,
"logging.db"
).build()
}
}
lütfen not edin @ApplicationContext
Hilt’in otomatik olarak alacağı anlamına gelen önceden tanımlanmış bağlamadır. ApplicationContext
senin için.
9. Arayüz örneklerini şununla enjekte edin: @Binds
Enjekte edilen alan bir arayüz ise, Hilt’e aşağıdakileri kullanarak arayüzün uygulanmasını nasıl sağlayacağını söylemeniz gerekir. @Binds
.
@InstallIn(ActivityComponent::class)
@Module
abstract class NavigationModule {
@Binds
abstract fun bindNavigator(impl: AppNavigatorImpl): AppNavigator
}
Lütfen soyut işleve ve sınıfa ihtiyaç duyulduğunu unutmayın. @Binds
.
10. Ekle @Qualifier
aynı arayüze sahip iki uygulama için
Alan enjeksiyonunuz bir arayüz ise ve birden fazla uygulamanız varsa, kullanmanız gerekir. @Qualifier
Hilt’e onları nasıl ayırt edeceğini söylemek.
Örneğin, eklemeniz gerekir @Qualifier
için LoggerLocalDataSource
ve LoggerInMemoryDataSource.
tanımlayın @Qualifier
bağlayan Hilt modüllerindeki sınıf LoggerLocalDataSource
ve LoggerInMemoryDataSource.
@Qualifier
annotation class InMemoryLogger
@Qualifier
annotation class DatabaseLogger
Ekle @DataBaseLogger
ve @InMemoryLogger
üstündeki niteleyiciler Binds
.
@InstallIn(SingletonComponent::class)
@Module
abstract class LoggingDatabaseModule {
@DatabaseLogger
@Binds
abstract fun bindDatabaseLogger(impl: LoggerLocalDataSource): LoggerDataSource
}
@InstallIn(ActivityComponent::class)
@Module
abstract class LoggingInMemoryModule {
@InMemoryLogger
@Binds
abstract fun bindInMemoryLogger(impl: LoggerInMemoryDataSource): LoggerDataSource
}
Hangi uygulamanın kullanılacağını belirtmek için alan ekleme değişkeninin üzerine bir niteleyici ekleyin. Örneğin, @DatabaseLogger
gösterir LoggerLocalDataSource
uygulanması kullanılacaktır.
@DatabaseLogger
@Inject lateinit var logger: LoggerDataSource
Çözüm
Dürüst olmak gerekirse, bağımlılık enjeksiyon kitaplığının hayranı değilim (şimdilik). Kodun anlaşılmasını zorlaştırır. Bir derleme hatası varsa, düzeltilmesi daha zordur. En azından benim için zor. Şimdilik, üretkenliğimi artırmıyor, tam tersi.
Öte yandan, servis bulucu teknik olarak bağımlılık enjeksiyonu değildir çünkü bağımlılıkları enjekte etmez. Tüketicilerin bağımlılıkları her yerden almalarını sağlar. Temelde küresel bir nesnedir.
Tüm bu nedenler göz önüne alındığında, hala manuel veya yapıcı bağımlılık enjeksiyonunu kullanmayı tercih ediyorum. Basit, anlaşılır ve hata ayıklaması kolaydır. Herkes kodunuzu anlayabilir. hepsi bu değil mi temiz kod hakkında?
Bunu söylediğimi biliyorum çünkü bağımlılık enjeksiyonunda ustalaşmadım. Umarım bir gün yaparım.