Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding kodein as dependency injection framework #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ dependencies {
implementation Dependencies.firebaseAuth
implementation Dependencies.googleAuth
implementation Dependencies.notification
implementation Dependencies.kodein
implementation Dependencies.kodeinConf

testImplementation DependenciesTest.junit4
androidTestImplementation DependenciesTest.androidRunner
Expand Down
23 changes: 21 additions & 2 deletions app/src/main/java/gdg/aracaju/GdgApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,30 @@ package gdg.aracaju

import android.app.Application
import com.jakewharton.threetenabp.AndroidThreeTen
import gdg.aracaju.data.di.dataModule
import gdg.aracaju.view.di.viewModule
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware
import org.kodein.di.conf.ConfigurableKodein
import org.kodein.di.generic.bind
import org.kodein.di.generic.provider

class GdgApplication : Application() {
class GdgApplication : Application(), KodeinAware {

private val appModule = Kodein.Module(name = "application"){
bind() from provider {
this@GdgApplication as Application
}
}

override val kodein: Kodein = ConfigurableKodein(mutable = true).apply {
addImport(appModule)
addImport(dataModule)
addImport(viewModule)
}

override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this);
AndroidThreeTen.init(this)
}
}
26 changes: 26 additions & 0 deletions app/src/main/java/gdg/aracaju/data/di/injection.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package gdg.aracaju.data.di

import gdg.aracaju.data.api.detail.DetailRepository
import gdg.aracaju.data.api.events.EventsRepository
import gdg.aracaju.data.api.login.AuthRepository
import gdg.aracaju.domain.service.AuthService
import gdg.aracaju.domain.service.DetailService
import gdg.aracaju.domain.service.EventsService
import org.kodein.di.Kodein
import org.kodein.di.generic.bind
import org.kodein.di.generic.singleton

val dataModule = Kodein.Module("data") {

bind<DetailService>() with singleton {
DetailRepository()
}

bind<EventsService>() with singleton {
EventsRepository()
}

bind<AuthService>() with singleton {
AuthRepository()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,34 @@ import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import com.xwray.groupie.GroupAdapter
import com.xwray.groupie.kotlinandroidextensions.ViewHolder
import gdg.aracaju.data.api.detail.DetailRepository
import gdg.aracaju.domain.Date
import gdg.aracaju.domain.model.Detail
import gdg.aracaju.domain.model.ScreenState
import gdg.aracaju.news.R
import gdg.aracaju.view.detail.map.MapsDetailActivity
import gdg.aracaju.view.kodein
import gdg.aracaju.view.viewModel
import kotlinx.android.synthetic.main.activity_detail.*
import kotlinx.android.synthetic.main.content_detail.*
import kotlinx.android.synthetic.main.error_state_layout.*
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware

class DetailActivity : AppCompatActivity() {
class DetailActivity : AppCompatActivity(), KodeinAware {

override val kodein: Kodein = kodein()

private val service by lazy { DetailRepository() }
private val sharer by lazy { Sharer(this) }
private val adapter by lazy { GroupAdapter<ViewHolder>() }
private val manager by lazy { LinearLayoutManager(this) }
private val calendar by lazy { CalendarEvent(this) }

private val id by lazy { intent?.extras?.get(ID) as? Int }

private val viewModel by lazy {
ViewModelProviders.of(this, DetailViewModelFactory(service)).get(DetailViewModel::class.java)
}
private val viewModel by viewModel<DetailViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand Down
43 changes: 43 additions & 0 deletions app/src/main/java/gdg/aracaju/view/di/injection.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package gdg.aracaju.view.di

import gdg.aracaju.domain.service.DetailService
import gdg.aracaju.domain.service.EventsService
import gdg.aracaju.view.detail.detail.DetailViewModel
import gdg.aracaju.view.detail.detail.DetailViewModelFactory
import gdg.aracaju.view.detail.detail.Sharer
import gdg.aracaju.view.login.AuthControl
import gdg.aracaju.view.login.AuthManager
import gdg.aracaju.view.login.LoginViewModel
import gdg.aracaju.view.login.LoginViewModelFactory
import gdg.aracaju.view.news.DashboardViewModel
import gdg.aracaju.view.news.DashboardViewModelFactory
import org.kodein.di.Kodein
import org.kodein.di.generic.bind
import org.kodein.di.generic.instance
import org.kodein.di.generic.provider

val viewModule = Kodein.Module("view"){

bind<AuthControl>() with provider {
AuthManager(
activity = instance(),
service = instance()
)
}

bind<DashboardViewModel>() with provider {
val service = instance<EventsService>()
val auth = instance<AuthControl>()
DashboardViewModelFactory(service, auth).create(DashboardViewModel::class.java)
}

bind<DetailViewModel>() with provider {
val service = instance<DetailService>()
DetailViewModelFactory(service).create(DetailViewModel::class.java)
}

bind<LoginViewModel>() with provider {
val service = instance<AuthControl>()
LoginViewModelFactory(service).create(LoginViewModel::class.java)
}
}
35 changes: 35 additions & 0 deletions app/src/main/java/gdg/aracaju/view/injection_extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package gdg.aracaju.view

import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware
import org.kodein.di.direct
import org.kodein.di.generic.instance
import org.kodein.di.generic.instanceOrNull

@Suppress("UNCHECKED_CAST")
inline fun <reified VM : ViewModel> KodeinAware.viewModel() = lazy {

val factory = object : ViewModelProvider.Factory {
override fun <Model : ViewModel> create(klass: Class<Model>) =
direct.instance<VM>() as Model
}

val host = direct.instanceOrNull<FragmentActivity>()
?: throw IllegalStateException("Host Activity not attached on this graph")

ViewModelProviders.of(host, factory).get(VM::class.java)
}

fun AppCompatActivity.kodein(bindings: Kodein.MainBuilder.() -> Unit = {}) = Kodein.lazy {

val parentKodein = (applicationContext as KodeinAware).kodein

extend(parentKodein)

bindings.invoke(this)
}
15 changes: 7 additions & 8 deletions app/src/main/java/gdg/aracaju/view/login/LoginActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,24 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.google.android.material.snackbar.Snackbar.LENGTH_SHORT
import com.google.android.material.snackbar.Snackbar.make
import gdg.aracaju.data.api.login.AuthRepository
import gdg.aracaju.domain.model.LoginState
import gdg.aracaju.domain.model.ScreenState
import gdg.aracaju.news.R
import gdg.aracaju.view.kodein
import gdg.aracaju.view.login.AuthManager.Companion.RC_SIGN_IN
import gdg.aracaju.view.news.DashboardActivity
import kotlinx.android.synthetic.main.activity_login.*
import gdg.aracaju.view.viewModel
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware

class LoginActivity : AppCompatActivity() {
class LoginActivity : AppCompatActivity(), KodeinAware {

private val service by lazy { AuthRepository() }
private val manager by lazy { AuthManager(this, service) }
override val kodein: Kodein = kodein()

private val viewModel by lazy {
ViewModelProviders.of(this, LoginViewModelFactory(manager)).get(LoginViewModel::class.java)
}
private val viewModel by viewModel<LoginViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand Down
19 changes: 8 additions & 11 deletions app/src/main/java/gdg/aracaju/view/news/DashboardActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,31 @@ import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.iid.FirebaseInstanceId
import com.xwray.groupie.GroupAdapter
import com.xwray.groupie.kotlinandroidextensions.ViewHolder
import gdg.aracaju.data.api.events.EventsRepository
import gdg.aracaju.data.api.login.AuthRepository
import gdg.aracaju.domain.model.Event
import gdg.aracaju.domain.model.ScreenState
import gdg.aracaju.news.R
import gdg.aracaju.view.detail.detail.DetailActivity
import gdg.aracaju.view.login.AuthManager
import gdg.aracaju.view.login.LoginActivity
import gdg.aracaju.view.kodein
import gdg.aracaju.view.viewModel
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.error_state_layout.*
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware

internal class DashboardActivity : AppCompatActivity() {
internal class DashboardActivity : AppCompatActivity(), KodeinAware {

override val kodein: Kodein = kodein()

private val eventService by lazy { EventsRepository() }
private val authService by lazy { AuthRepository() }
private val auth by lazy { AuthManager(this, authService) }

private val viewModel by lazy {
ViewModelProviders
.of(this, DashboardViewModelFactory(eventService, auth))
.get(DashboardViewModel::class.java)
}
private val viewModel by viewModel<DashboardViewModel>()
private val adapter by lazy { GroupAdapter<ViewHolder>() }
private val manager by lazy { LinearLayoutManager(this) }
private val bottomNavDrawerFragment by lazy { BottomNavigationDrawerFragment() }
Expand Down
4 changes: 4 additions & 0 deletions buildSrc/src/main/java/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ object Versions {
const val notification = "17.6.0"
const val fabric = "1.26.1"
const val crashlytics = "2.9.9"
const val kodein = "6.0.1"
}

object Dependencies {
Expand Down Expand Up @@ -54,6 +55,9 @@ object Dependencies {
const val threetenabp = "com.jakewharton.threetenabp:threetenabp:${Versions.threeten}"

const val notification = "com.google.firebase:firebase-messaging:${Versions.notification}"

val kodein = "org.kodein.di:kodein-di-generic-jvm:${Versions.kodein}"
val kodeinConf = "org.kodein.di:kodein-di-conf-jvm:${Versions.kodein}"
}

object VersionsTest {
Expand Down
Binary file removed release_keystore.jks
Binary file not shown.