Skip to content

Commit

Permalink
feat: migrate to Dagger-Hilt for DI
Browse files Browse the repository at this point in the history
  • Loading branch information
RivuChk committed Jul 1, 2020
1 parent bc964da commit 21a9db6
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 51 deletions.
34 changes: 19 additions & 15 deletions app/build.gradle
@@ -1,13 +1,15 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlinx-serialization'

apply plugin: 'jacoco'

// junit5 doesn't support android projects out of the box
apply plugin: 'de.mannodermaus.android-junit5'
plugins {
id "com.android.application"
id "kotlin-android"
id "kotlin-android-extensions"
id "kotlin-kapt"
id "kotlinx-serialization"
id "dagger.hilt.android.plugin"

id "jacoco"
// junit5 doesn't support android projects out of the box
id "de.mannodermaus.android-junit5"
}

android {
compileSdkVersion 30
Expand Down Expand Up @@ -92,7 +94,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.lifecycle:lifecycle-reactivestreams-ktx:2.3.0-alpha04'
implementation 'androidx.lifecycle:lifecycle-reactivestreams-ktx:2.3.0-alpha05'

implementation "androidx.compose:compose-runtime:$compose_version"
implementation "androidx.ui:ui-foundation:$compose_version"
Expand All @@ -102,10 +104,12 @@ dependencies {
implementation "androidx.ui:ui-material:$compose_version"
implementation "androidx.ui:ui-livedata:$compose_version"

def koin_version = "2.1.5"
implementation "org.koin:koin-android:$koin_version"
implementation "org.koin:koin-androidx-scope:$koin_version"
implementation "org.koin:koin-androidx-viewmodel:$koin_version"
implementation "com.google.dagger:hilt-android:$dagger_hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$dagger_hilt_version"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:$dagger_hilt_androidx_version"
kapt "androidx.hilt:hilt-compiler:$dagger_hilt_androidx_version"
implementation "androidx.core:core-ktx:1.3.0"
implementation "androidx.activity:activity-ktx:1.1.0"

//RxJava
implementation "io.reactivex.rxjava3:rxjava:3.0.2"
Expand Down
@@ -1,22 +1,24 @@
package dev.rivu.mvijetpackcomposedemo

import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.ui.core.setContent
import androidx.ui.material.MaterialTheme
import dagger.hilt.android.AndroidEntryPoint
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieIntent
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieViewModel
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.isDetailState
import dev.rivu.mvijetpackcomposedemo.moviesearch.ui.MoviesScreen
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.subjects.PublishSubject
import org.koin.androidx.viewmodel.ext.android.viewModel
import timber.log.Timber

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

val moviesViewModel: MovieViewModel by viewModel()
val moviesViewModel: MovieViewModel by viewModels()

val liveData by lazy {
moviesViewModel.states()
Expand Down
15 changes: 2 additions & 13 deletions app/src/main/java/dev/rivu/mvijetpackcomposedemo/MovieApp.kt
@@ -1,25 +1,14 @@
package dev.rivu.mvijetpackcomposedemo

import android.app.Application
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.injection.dataModule
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.injection.presentationModule
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber

@HiltAndroidApp
class MovieApp : Application() {
override fun onCreate() {
super.onCreate()

startKoin {
androidLogger()
// declare used Android context
androidContext(applicationContext)
// declare modules
modules(dataModule, presentationModule)
}

if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
} else {
Expand Down
@@ -1,6 +1,5 @@
package dev.rivu.mvijetpackcomposedemo.moviesearch.presentation
package dev.rivu.mvijetpackcomposedemo.base.presentation

import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Scheduler
import io.reactivex.rxjava3.schedulers.Schedulers
Expand Down
@@ -0,0 +1,19 @@
package dev.rivu.mvijetpackcomposedemo.base.presentation.injection

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ApplicationComponent
import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
import dev.rivu.mvijetpackcomposedemo.base.presentation.SchedulerProvider
import javax.inject.Singleton

@Module
@InstallIn(ApplicationComponent::class)
object AppPresentationModule {

@Provides
@Singleton
fun provideSchedulerProvider(): ISchedulerProvider =
SchedulerProvider()
}
@@ -1,26 +1,63 @@
package dev.rivu.mvijetpackcomposedemo.moviesearch.data.injection

import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.components.ApplicationComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.IMovieRepository
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.MovieDataStore
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.MovieRepository
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.LocalMovieDataStore
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieDB
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.local.database.MovieDao
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.remote.MovieApi
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.remote.MovieApiFactory
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.remote.RemoteMovieDataStore
import org.koin.core.qualifier.named
import org.koin.dsl.module
import javax.inject.Named
import javax.inject.Singleton

val dataModule = module {
@Module
@InstallIn(ActivityComponent::class)
object DataModule {

single { MovieApiFactory.makeMovieApi() }

single { MovieDB.getInstance(get()) }
@Provides
@Named("local")
fun provideLocalMovieDataStore(dao: MovieDao): MovieDataStore = LocalMovieDataStore(dao)

single { get<MovieDB>().movieDao() }

single<MovieDataStore>(named("local")) { LocalMovieDataStore(get()) }
single<MovieDataStore>(named("remote")) { RemoteMovieDataStore(get()) }
@Provides
@Named("remote")
fun provideRemoteMovieDataStore(api: MovieApi): MovieDataStore = RemoteMovieDataStore(api)


@Provides
fun provideMovieRepository(
@Named("local") localMovieDataStore: MovieDataStore,
@Named("remote") remoteMovieDataStore: MovieDataStore
): IMovieRepository = MovieRepository(localMovieDataStore, remoteMovieDataStore)
}

@Module
@InstallIn(ApplicationComponent::class)
object AppDataModule {

@Provides
@Singleton
fun provideMovieApi(): MovieApi = MovieApiFactory.makeMovieApi()


@Provides
@Singleton
fun provideDB(@ApplicationContext context: Context): MovieDB = MovieDB.getInstance(context)


@Provides
@Singleton
fun provideMovieDao(db: MovieDB): MovieDao = db.movieDao()


single<IMovieRepository> { MovieRepository(get(named("local")), get(named("remote"))) }
}
@@ -1,12 +1,13 @@
package dev.rivu.mvijetpackcomposedemo.moviesearch.presentation

import androidx.hilt.lifecycle.ViewModelInject
import dev.rivu.mvijetpackcomposedemo.base.presentation.BaseViewModel
import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.FlowableTransformer
import io.reactivex.rxjava3.functions.BiFunction

class MovieViewModel(
class MovieViewModel @ViewModelInject constructor(
override val actionProcessor: MovieProcessor
) :
BaseViewModel<MovieIntent, MoviesState, MovieAction, MovieResult>() {
Expand Down
@@ -1,17 +1,18 @@
package dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.injection

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dev.rivu.mvijetpackcomposedemo.base.presentation.ISchedulerProvider
import dev.rivu.mvijetpackcomposedemo.moviesearch.data.IMovieRepository
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieProcessor
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.MovieViewModel
import dev.rivu.mvijetpackcomposedemo.moviesearch.presentation.SchedulerProvider
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module

val presentationModule = module {
@Module
@InstallIn(ActivityComponent::class)
object PresentationModule {

single<ISchedulerProvider> { SchedulerProvider() }

single { MovieProcessor(get(), get()) }
viewModel { MovieViewModel(get()) }
@Provides
fun provideMovieProcessor(repository: IMovieRepository, schedulerProvider: ISchedulerProvider) = MovieProcessor(repository, schedulerProvider)

}
3 changes: 3 additions & 0 deletions build.gradle
Expand Up @@ -4,6 +4,8 @@ buildscript {
def compose_release_version = "dev14"
ext.compose_version = "0.1.0-$compose_release_version"
ext.compose_compiler_extension_version = "0.1.0-$compose_release_version"
ext.dagger_hilt_version = "2.28-alpha"
ext.dagger_hilt_androidx_version = "1.0.0-alpha01"
repositories {
google()
jcenter()
Expand All @@ -14,6 +16,7 @@ buildscript {
classpath "de.mannodermaus.gradle.plugins:android-junit5:$android_junit5_version"
classpath "org.jacoco:org.jacoco.core:$jacoco_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$dagger_hilt_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
Expand Down

0 comments on commit 21a9db6

Please sign in to comment.