Skip to content

Commit 21a9db6

Browse files
committed
feat: migrate to Dagger-Hilt for DI
1 parent bc964da commit 21a9db6

File tree

9 files changed

+106
-51
lines changed

9 files changed

+106
-51
lines changed

app/build.gradle

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
apply plugin: 'com.android.application'
2-
apply plugin: 'kotlin-android'
3-
apply plugin: 'kotlin-android-extensions'
4-
apply plugin: 'kotlin-kapt'
5-
apply plugin: 'kotlinx-serialization'
6-
7-
apply plugin: 'jacoco'
8-
9-
// junit5 doesn't support android projects out of the box
10-
apply plugin: 'de.mannodermaus.android-junit5'
1+
plugins {
2+
id "com.android.application"
3+
id "kotlin-android"
4+
id "kotlin-android-extensions"
5+
id "kotlin-kapt"
6+
id "kotlinx-serialization"
7+
id "dagger.hilt.android.plugin"
8+
9+
id "jacoco"
10+
// junit5 doesn't support android projects out of the box
11+
id "de.mannodermaus.android-junit5"
12+
}
1113

1214
android {
1315
compileSdkVersion 30
@@ -92,7 +94,7 @@ dependencies {
9294
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
9395
implementation 'androidx.core:core-ktx:1.3.0'
9496
implementation 'androidx.appcompat:appcompat:1.1.0'
95-
implementation 'androidx.lifecycle:lifecycle-reactivestreams-ktx:2.3.0-alpha04'
97+
implementation 'androidx.lifecycle:lifecycle-reactivestreams-ktx:2.3.0-alpha05'
9698

9799
implementation "androidx.compose:compose-runtime:$compose_version"
98100
implementation "androidx.ui:ui-foundation:$compose_version"
@@ -102,10 +104,12 @@ dependencies {
102104
implementation "androidx.ui:ui-material:$compose_version"
103105
implementation "androidx.ui:ui-livedata:$compose_version"
104106

105-
def koin_version = "2.1.5"
106-
implementation "org.koin:koin-android:$koin_version"
107-
implementation "org.koin:koin-androidx-scope:$koin_version"
108-
implementation "org.koin:koin-androidx-viewmodel:$koin_version"
107+
implementation "com.google.dagger:hilt-android:$dagger_hilt_version"
108+
kapt "com.google.dagger:hilt-android-compiler:$dagger_hilt_version"
109+
implementation "androidx.hilt:hilt-lifecycle-viewmodel:$dagger_hilt_androidx_version"
110+
kapt "androidx.hilt:hilt-compiler:$dagger_hilt_androidx_version"
111+
implementation "androidx.core:core-ktx:1.3.0"
112+
implementation "androidx.activity:activity-ktx:1.1.0"
109113

110114
//RxJava
111115
implementation "io.reactivex.rxjava3:rxjava:3.0.2"

app/src/main/java/dev/rivu/mvijetpackcomposedemo/MainActivity.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
package dev.rivu.mvijetpackcomposedemo
22

33
import android.os.Bundle
4+
import androidx.activity.viewModels
45
import androidx.appcompat.app.AppCompatActivity
56
import androidx.lifecycle.Observer
67
import androidx.ui.core.setContent
78
import androidx.ui.material.MaterialTheme
9+
import dagger.hilt.android.AndroidEntryPoint
810
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieIntent
911
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieViewModel
1012
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.isDetailState
1113
import dev.rivu.mvijetpackcomposedemo.moviesearch.ui.MoviesScreen
1214
import io.reactivex.rxjava3.core.Observable
1315
import io.reactivex.rxjava3.subjects.PublishSubject
14-
import org.koin.androidx.viewmodel.ext.android.viewModel
1516
import timber.log.Timber
1617

18+
@AndroidEntryPoint
1719
class MainActivity : AppCompatActivity() {
1820

19-
val moviesViewModel: MovieViewModel by viewModel()
21+
val moviesViewModel: MovieViewModel by viewModels()
2022

2123
val liveData by lazy {
2224
moviesViewModel.states()

app/src/main/java/dev/rivu/mvijetpackcomposedemo/MovieApp.kt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
11
package dev.rivu.mvijetpackcomposedemo
22

33
import android.app.Application
4-
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.injection.dataModule
5-
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.injection.presentationModule
6-
import org.koin.android.ext.koin.androidContext
7-
import org.koin.android.ext.koin.androidLogger
8-
import org.koin.core.context.startKoin
4+
import dagger.hilt.android.HiltAndroidApp
95
import timber.log.Timber
106

7+
@HiltAndroidApp
118
class MovieApp : Application() {
129
override fun onCreate() {
1310
super.onCreate()
1411

15-
startKoin {
16-
androidLogger()
17-
// declare used Android context
18-
androidContext(applicationContext)
19-
// declare modules
20-
modules(dataModule, presentationModule)
21-
}
22-
2312
if (BuildConfig.DEBUG) {
2413
Timber.plant(Timber.DebugTree())
2514
} else {
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
package dev.rivu.mvijetpackcomposedemo.moviesearch.presentation
1+
package dev.rivu.mvijetpackcomposedemo.base.presentation
22

3-
import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
43
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
54
import io.reactivex.rxjava3.core.Scheduler
65
import io.reactivex.rxjava3.schedulers.Schedulers
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package dev.rivu.mvijetpackcomposedemo.base.presentation.injection
2+
3+
import dagger.Module
4+
import dagger.Provides
5+
import dagger.hilt.InstallIn
6+
import dagger.hilt.android.components.ApplicationComponent
7+
import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
8+
import dev.rivu.mvijetpackcomposedemo.base.presentation.SchedulerProvider
9+
import javax.inject.Singleton
10+
11+
@Module
12+
@InstallIn(ApplicationComponent::class)
13+
object AppPresentationModule {
14+
15+
@Provides
16+
@Singleton
17+
fun provideSchedulerProvider(): ISchedulerProvider =
18+
SchedulerProvider()
19+
}
Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,63 @@
11
package dev.rivu.mvijetpackcomposedemo.moviesearch.data.injection
22

3+
import android.content.Context
4+
import dagger.Module
5+
import dagger.Provides
6+
import dagger.hilt.InstallIn
7+
import dagger.hilt.android.components.ActivityComponent
8+
import dagger.hilt.android.components.ApplicationComponent
9+
import dagger.hilt.android.qualifiers.ApplicationContext
310
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.IMovieRepository
411
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.MovieDataStore
512
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.MovieRepository
613
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.LocalMovieDataStore
714
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieDB
15+
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieDao
816
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.remote.MovieApi
917
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.remote.MovieApiFactory
1018
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.remote.RemoteMovieDataStore
11-
import org.koin.core.qualifier.named
12-
import org.koin.dsl.module
19+
import javax.inject.Named
20+
import javax.inject.Singleton
1321

14-
val dataModule = module {
22+
@Module
23+
@InstallIn(ActivityComponent::class)
24+
object DataModule {
1525

16-
single { MovieApiFactory.makeMovieApi() }
1726

18-
single { MovieDB.getInstance(get()) }
27+
@Provides
28+
@Named("local")
29+
fun provideLocalMovieDataStore(dao: MovieDao): MovieDataStore = LocalMovieDataStore(dao)
1930

20-
single { get<MovieDB>().movieDao() }
2131

22-
single<MovieDataStore>(named("local")) { LocalMovieDataStore(get()) }
23-
single<MovieDataStore>(named("remote")) { RemoteMovieDataStore(get()) }
32+
@Provides
33+
@Named("remote")
34+
fun provideRemoteMovieDataStore(api: MovieApi): MovieDataStore = RemoteMovieDataStore(api)
35+
36+
37+
@Provides
38+
fun provideMovieRepository(
39+
@Named("local") localMovieDataStore: MovieDataStore,
40+
@Named("remote") remoteMovieDataStore: MovieDataStore
41+
): IMovieRepository = MovieRepository(localMovieDataStore, remoteMovieDataStore)
42+
}
43+
44+
@Module
45+
@InstallIn(ApplicationComponent::class)
46+
object AppDataModule {
47+
48+
@Provides
49+
@Singleton
50+
fun provideMovieApi(): MovieApi = MovieApiFactory.makeMovieApi()
51+
52+
53+
@Provides
54+
@Singleton
55+
fun provideDB(@ApplicationContext context: Context): MovieDB = MovieDB.getInstance(context)
56+
57+
58+
@Provides
59+
@Singleton
60+
fun provideMovieDao(db: MovieDB): MovieDao = db.movieDao()
61+
2462

25-
single<IMovieRepository> { MovieRepository(get(named("local")), get(named("remote"))) }
2663
}

app/src/main/java/dev/rivu/mvijetpackcomposedemo/moviesearch/presentation/MovieViewModel.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package dev.rivu.mvijetpackcomposedemo.moviesearch.presentation
22

3+
import androidx.hilt.lifecycle.ViewModelInject
34
import dev.rivu.mvijetpackcomposedemo.base.presentation.BaseViewModel
45
import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
56
import io.reactivex.rxjava3.core.Flowable
67
import io.reactivex.rxjava3.core.FlowableTransformer
78
import io.reactivex.rxjava3.functions.BiFunction
89

9-
class MovieViewModel(
10+
class MovieViewModel @ViewModelInject constructor(
1011
override val actionProcessor: MovieProcessor
1112
) :
1213
BaseViewModel<MovieIntent, MoviesState, MovieAction, MovieResult>() {
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.injection
22

3+
import dagger.Module
4+
import dagger.Provides
5+
import dagger.hilt.InstallIn
6+
import dagger.hilt.android.components.ActivityComponent
37
import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
8+
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.IMovieRepository
49
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieProcessor
5-
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieViewModel
6-
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.SchedulerProvider
7-
import org.koin.androidx.viewmodel.dsl.viewModel
8-
import org.koin.dsl.module
910

10-
val presentationModule = module {
11+
@Module
12+
@InstallIn(ActivityComponent::class)
13+
object PresentationModule {
1114

12-
single<ISchedulerProvider> { SchedulerProvider() }
13-
14-
single { MovieProcessor(get(), get()) }
15-
viewModel { MovieViewModel(get()) }
15+
@Provides
16+
fun provideMovieProcessor(repository: IMovieRepository, schedulerProvider: ISchedulerProvider) = MovieProcessor(repository, schedulerProvider)
1617

1718
}

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ buildscript {
44
def compose_release_version = "dev14"
55
ext.compose_version = "0.1.0-$compose_release_version"
66
ext.compose_compiler_extension_version = "0.1.0-$compose_release_version"
7+
ext.dagger_hilt_version = "2.28-alpha"
8+
ext.dagger_hilt_androidx_version = "1.0.0-alpha01"
79
repositories {
810
google()
911
jcenter()
@@ -14,6 +16,7 @@ buildscript {
1416
classpath "de.mannodermaus.gradle.plugins:android-junit5:$android_junit5_version"
1517
classpath "org.jacoco:org.jacoco.core:$jacoco_version"
1618
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
19+
classpath "com.google.dagger:hilt-android-gradle-plugin:$dagger_hilt_version"
1720
// NOTE: Do not place your application dependencies here; they belong
1821
// in the individual module build.gradle files
1922
}

0 commit comments

Comments
 (0)