Add KOIN for dependency injection

This commit is contained in:
cketti 2018-03-24 05:30:32 +01:00
parent 5ebc9e400c
commit 15cf1dff82
10 changed files with 97 additions and 14 deletions

View file

@ -3,6 +3,7 @@ androidCompileSdkVersion=27
androidBuildToolsVersion=27.0.3
androidSupportLibraryVersion=27.0.2
timberVersion=4.5.1
koinVersion=0.9.1
robolectricVersion=3.7.1
junitVersion=4.12

View file

@ -42,6 +42,7 @@ dependencies {
implementation 'com.xwray:groupie:2.0.3'
implementation 'com.xwray:groupie-kotlin-android-extensions:2.0.3'
implementation "org.jetbrains.anko:anko-coroutines:0.10.4"
implementation "org.koin:koin-android-architecture:${koinVersion}"
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
@ -50,6 +51,7 @@ dependencies {
testImplementation "com.google.truth:truth:${truthVersion}"
testImplementation "org.mockito:mockito-core:${mockitoVersion}"
testImplementation "org.jdom:jdom2:2.0.6"
testImplementation "org.koin:koin-test:${koinVersion}"
}
android {

View file

@ -0,0 +1,43 @@
package com.fsck.k9
import android.app.Application
import com.fsck.k9.ui.settings.settingsUiModule
import org.koin.Koin
import org.koin.KoinContext
import org.koin.android.ext.koin.with
import org.koin.android.logger.AndroidLogger
import org.koin.core.parameter.Parameters
import org.koin.dsl.module.applicationContext
import org.koin.log.EmptyLogger
import org.koin.standalone.StandAloneContext
object DI {
private val mainModule = applicationContext {
bean { Preferences.getPreferences(get()) }
}
val appModules = listOf(
mainModule,
settingsUiModule
)
@JvmStatic fun start(application: Application) {
@Suppress("ConstantConditionIf")
Koin.logger = if (BuildConfig.DEBUG) AndroidLogger() else EmptyLogger()
StandAloneContext.startKoin(appModules) with application
}
@JvmOverloads
@JvmStatic
fun <T : Any> get(clazz: Class<T>, name: String = "", parameters: Parameters = { emptyMap() }): T {
val koinContext = StandAloneContext.koinContext as KoinContext
val kClass = clazz.kotlin
return if (name.isEmpty()) {
koinContext.resolveInstance(kClass, parameters) { koinContext.beanRegistry.searchAll(kClass) }
} else {
koinContext.resolveInstance(kClass, parameters) { koinContext.beanRegistry.searchByName(name) }
}
}
}

View file

@ -530,6 +530,7 @@ public class K9 extends Application {
super.onCreate();
app = this;
DI.start(this);
Globals.setContext(this);
K9MailLib.setDebugStatus(new K9MailLib.DebugStatus() {

View file

@ -1,29 +1,28 @@
package com.fsck.k9.ui.account
import android.arch.lifecycle.LiveData
import android.content.Context
import com.fsck.k9.Account
import com.fsck.k9.Preferences
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import org.jetbrains.anko.coroutines.experimental.bg
class AccountsLiveData(context: Context) : LiveData<List<Account>>() {
class AccountsLiveData(val preferences: Preferences) : LiveData<List<Account>>() {
init {
loadAccountsAsync(context)
loadAccountsAsync()
}
private fun loadAccountsAsync(context: Context) {
private fun loadAccountsAsync() {
launch(UI) {
val accounts = bg {
loadAccounts(context)
loadAccounts()
}
value = accounts.await()
}
}
private fun loadAccounts(context: Context): List<Account> {
return Preferences.getPreferences(context).accounts
private fun loadAccounts(): List<Account> {
return preferences.accounts
}
}

View file

@ -0,0 +1,10 @@
package com.fsck.k9.ui.settings
import com.fsck.k9.ui.account.AccountsLiveData
import org.koin.android.architecture.ext.viewModel
import org.koin.dsl.module.applicationContext
val settingsUiModule = applicationContext {
bean { AccountsLiveData(get()) }
viewModel { SettingsViewModel(get()) }
}

View file

@ -1,7 +1,6 @@
package com.fsck.k9.ui.settings
import android.app.Activity
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
@ -16,8 +15,11 @@ import com.xwray.groupie.Item
import com.xwray.groupie.Section
import com.xwray.groupie.kotlinandroidextensions.ViewHolder
import kotlinx.android.synthetic.main.activity_settings.*
import org.koin.android.architecture.ext.viewModel
class SettingsActivity : K9Activity() {
private val viewModel: SettingsViewModel by viewModel()
private lateinit var settingsAdapter: GroupAdapter<ViewHolder>
@ -48,7 +50,6 @@ class SettingsActivity : K9Activity() {
}
private fun populateSettingsList() {
val viewModel = ViewModelProviders.of(this).get(SettingsViewModel::class.java)
viewModel.accounts.observe(this) { accounts ->
populateSettingsList(accounts)
}

View file

@ -1,9 +1,6 @@
package com.fsck.k9.ui.settings
import android.app.Application
import android.arch.lifecycle.AndroidViewModel
import android.arch.lifecycle.ViewModel
import com.fsck.k9.ui.account.AccountsLiveData
internal class SettingsViewModel(application: Application) : AndroidViewModel(application) {
val accounts = AccountsLiveData(application)
}
internal class SettingsViewModel(val accounts: AccountsLiveData) : ViewModel()

View file

@ -0,0 +1,15 @@
package com.fsck.k9
import org.junit.Test
import org.koin.Koin
import org.koin.log.PrintLogger
import org.koin.test.dryRun
class DependencyInjectionTest : K9RobolectricTest() {
@Test
fun testDependencyTree() {
Koin.logger = PrintLogger()
dryRun()
}
}

View file

@ -0,0 +1,14 @@
package com.fsck.k9
import android.app.Application
import org.junit.runner.RunWith
import org.koin.test.AutoCloseKoinTest
import org.robolectric.RobolectricTestRunner
/**
* A Robolectric test that creates an instance of our [Application] class [K9].
*
* See also [RobolectricTest].
*/
@RunWith(RobolectricTestRunner::class)
abstract class K9RobolectricTest : AutoCloseKoinTest()