Android Injection : Simple Example (Dagger 2 — Hilt — Koin) : 2/2

Mohammed Kadi
4 min readFeb 13, 2021

--

Photo by Denny Müller on Unsplash

continue with project for compare Android injection in (Dagger 2 — Hilt — Koin) of this cases :

  • class with constructor
  • class with constructor (With Parameter)
  • SharedPreference
  • Sqlite
  • ViewModel
  • Room
  • Room : RecyclerView

The source code of application :

Inject : Sqlite

Dagger 2

add Class User

add class DbHelper

Class DbHelper need context, so we add @ApplicationContext as annotation class ApplicationContext and add annotation class DatabaseInfo

in Component

In App Class create Component object and pass context

In MainActivity

Dagger Hilt

add Class User

add class DbHelper

Class DbHelper need context, so we use @ApplicationContext directly and in model

no need to Component

In App Class create Component object and pass context

@HiltAndroidApp
class MyApp : Application()

In MainActivity

Koin

add Class User

add class DbHelper

Class DbHelper need context, so we use androidContext() directly and in model

no need to Component

In App Class create Component object and pass context

In MainActivity

Inject : Room

The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.

add in build.gradle of your app

Dagger 2

add Class User

add interface UserDao

add abstract class UserRoomDatabase

add class UserRepository

in Module

in Component

In App Class create Component object and pass context

In MainActivity

Dagger Hilt

add Class User

add interface UserDao

add abstract class UserRoomDatabase

add class UserRepository

in Module

no need to Component

In App Class

@HiltAndroidApp
class MyApp : Application()

In MainActivity

Koin

add Class User

@Entity(tableName = "users")
class User(val usr_name: String) {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
}

add interface UserDao

@Dao
interface UserDao {
@Insert //(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(user: User)
@Query("DELETE FROM users")
suspend fun deleteAll()
@Query("SELECT * from users ORDER BY id Desc")
fun getAllUsers(): Flow<List<User>>
@Query("SELECT * from users where id = :userid")
fun getUser(userid: String): User
}

add abstract class UserRoomDatabase

add class UserRepository

class UserRepository(private val userDao: UserDao) {
val allUsers: Flow<List<User>> = userDao.getAllUsers()
@WorkerThread
suspend fun insert(User: String) = withContext(Dispatchers.IO) {
userDao.insert(User(User))
}
@WorkerThread
suspend fun insert(User: User) = withContext(Dispatchers.IO) {
userDao.insert(User)
}
@WorkerThread
suspend fun deleteAllUsers() = withContext(Dispatchers.IO) {
userDao.deleteAll()
}
}

in Module

MyModule.kt

no need to Component

In App Class

class MyApp : Application() {    override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@MyApp)
modules(listOf(MyModule, MyViewModelModule))
}
}
}

In MainActivity

Inject : Room RecyclerView

Dagger 2

add class UserListAdapter : need a context

add class UsersViewModel

class UsersViewModel(private val repository: UserRepository) : ViewModel() {
val allUsers: LiveData<List<User>>
get() = repository.allUsers.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user: String) {
viewModelScope.launch {
repository.insert(user)
}
}
fun deleteAllUsers() {
viewModelScope.launch {
repository.deleteAllUsers()
}
}
}

in Module

@Module
internal class MyModule {
@Provides
@Singleton
fun provideCar3(): Car3 = Car3()
// Inject room
@Provides
@Singleton
fun provideUserDao(@ApplicationContext appContext: Context): UserDao =
UserRoomDatabase.getDatabase(appContext).userDao()
@Provides
@Singleton
fun provideUserRepository(userDao: UserDao): UserRepository = UserRepository(userDao)
@Provides
@Singleton
fun provideUsersViewModel(userRepository: UserRepository): UsersViewModel = UsersViewModel(userRepository)
}

in Component

@Singleton
@Component(modules = [MyModule::class, ContextModule::class, ViewModelModule::class])
interface MyComponent {
fun inject(target: MainActivity)
}

In App Class create Component object and pass context

class MyApp : Application() {
var myComponent: MyComponent? = null
private set
override fun onCreate() {
super.onCreate()
// myComponent = DaggerMyComponent.create()
myComponent = DaggerMyComponent.builder().contextModule(ContextModule(this)).build()
}
}

In MainActivity

Dagger Hilt

add class UserListAdapter : need a context

add class UsersViewModel

in Module

no need to Component

In App Class create Component object and pass context

@HiltAndroidApp
class MyApp : Application()

In MainActivity

Koin

add class UserListAdapter : need a context

add class UsersViewModel

class UsersViewModel(private val repository: UserRepository) : ViewModel() {
val allUsers: LiveData<List<User>>
get() = repository.allUsers.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user: String) {
viewModelScope.launch {
repository.insert(user)
}
}
fun deleteAllUsers() {
viewModelScope.launch {
repository.deleteAllUsers()
}
}
}

in Module

no need to Component

In App Class create Component object and pass context

class MyApp : Application() {    override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@MyApp)
modules(listOf(MyModule, MyViewModelModule))
}
}
}

In MainActivity

The source code of application :

--

--