From 3b66420f0a43b68c120fcf071f0afed2f210ce9e Mon Sep 17 00:00:00 2001 From: lucassales Date: Tue, 28 May 2019 10:57:23 +0200 Subject: [PATCH 1/3] Replacing dagger for koin --- app/build.gradle | 10 +- app/src/main/java/dk/nodes/template/App.kt | 33 ++-- .../template/inititializers/AppInitializer.kt | 3 +- .../injection/components/AppComponent.kt | 32 ---- .../template/injection/modules/AppModule.kt | 23 --- .../injection/modules/ExecutorModule.kt | 16 -- .../injection/modules/InteractorModule.kt | 6 - .../template/injection/modules/RestModule.kt | 96 ------------ .../modules/RestRepositoryBinding.kt | 14 -- .../injection/modules/StorageBindingModule.kt | 14 -- .../template/injection/modules/appModule.kt | 9 ++ .../template/injection/modules/restModule.kt | 62 ++++++++ .../injection/modules/restRepositoryModule.kt | 9 ++ .../injection/modules/storageModule.kt | 9 ++ build.gradle | 4 +- data/build.gradle | 2 +- .../template/network/RestPostRepository.kt | 3 +- domain/build.gradle | 2 +- .../domain/interactors/PostsInteractor.kt | 6 +- .../domain/modules/interactorModule.kt | 8 + presentation/build.gradle | 8 +- .../extensions/LifecycleOwnerExtensions.kt | 144 +++++++++--------- .../injection/DaggerViewModelFactory.kt | 31 ---- .../injection/ViewModelBuilder.kt | 17 --- .../presentation/injection/ViewModelKey.kt | 14 -- .../presentation/injection/viewModelModule.kt | 9 ++ .../presentation/ui/base/BaseActivity.kt | 18 +-- .../presentation/ui/base/BaseFragment.kt | 27 +--- .../presentation/ui/main/MainActivity.kt | 1 + .../ui/main/MainActivityBuilder.kt | 20 --- .../ui/main/MainActivityModule.kt | 8 + .../ui/main/MainActivityViewModel.kt | 5 +- 32 files changed, 233 insertions(+), 430 deletions(-) delete mode 100644 app/src/main/java/dk/nodes/template/injection/components/AppComponent.kt delete mode 100644 app/src/main/java/dk/nodes/template/injection/modules/AppModule.kt delete mode 100644 app/src/main/java/dk/nodes/template/injection/modules/ExecutorModule.kt delete mode 100644 app/src/main/java/dk/nodes/template/injection/modules/InteractorModule.kt delete mode 100644 app/src/main/java/dk/nodes/template/injection/modules/RestModule.kt delete mode 100644 app/src/main/java/dk/nodes/template/injection/modules/RestRepositoryBinding.kt delete mode 100644 app/src/main/java/dk/nodes/template/injection/modules/StorageBindingModule.kt create mode 100644 app/src/main/java/dk/nodes/template/injection/modules/appModule.kt create mode 100644 app/src/main/java/dk/nodes/template/injection/modules/restModule.kt create mode 100644 app/src/main/java/dk/nodes/template/injection/modules/restRepositoryModule.kt create mode 100644 app/src/main/java/dk/nodes/template/injection/modules/storageModule.kt create mode 100644 domain/src/main/java/dk/nodes/template/domain/modules/interactorModule.kt delete mode 100644 presentation/src/main/java/dk/nodes/template/presentation/injection/DaggerViewModelFactory.kt delete mode 100644 presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelBuilder.kt delete mode 100644 presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelKey.kt create mode 100644 presentation/src/main/java/dk/nodes/template/presentation/injection/viewModelModule.kt delete mode 100644 presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityBuilder.kt create mode 100644 presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityModule.kt diff --git a/app/build.gradle b/app/build.gradle index 795a0ae4..60b16c89 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -112,10 +112,12 @@ dependencies { implementation "androidx.constraintlayout:constraintlayout:${versions.constraint_layout}" implementation 'androidx.multidex:multidex:2.0.1' - implementation "com.google.dagger:dagger-android:${versions.dagger}" - implementation "com.google.dagger:dagger-android-support:${versions.dagger}" - kapt "com.google.dagger:dagger-compiler:${versions.dagger}" - kapt "com.google.dagger:dagger-android-processor:${versions.dagger}" + implementation "org.koin:koin-core:${versions.koin}" + + implementation "org.koin:koin-android-scope:${versions.koin}" + implementation "org.koin:koin-android-viewmodel:${versions.koin}" + implementation "org.koin:koin-android-ext:${versions.koin}" + implementation "net.hockeyapp.android:HockeySDK:${versions.hockey_sdk}" implementation "com.jakewharton.timber:timber:${versions.timber}" diff --git a/app/src/main/java/dk/nodes/template/App.kt b/app/src/main/java/dk/nodes/template/App.kt index 49dbe02e..226735ae 100644 --- a/app/src/main/java/dk/nodes/template/App.kt +++ b/app/src/main/java/dk/nodes/template/App.kt @@ -1,18 +1,35 @@ package dk.nodes.template +import android.app.Application import android.content.Context import androidx.multidex.MultiDex -import dagger.android.AndroidInjector -import dagger.android.DaggerApplication +import dk.nodes.template.domain.modules.interactorModule import dk.nodes.template.inititializers.AppInitializer -import dk.nodes.template.injection.components.DaggerAppComponent -import javax.inject.Inject +import dk.nodes.template.injection.modules.appModule +import dk.nodes.template.injection.modules.restModule +import dk.nodes.template.injection.modules.restRepositoryModule +import dk.nodes.template.injection.modules.storageModule +import dk.nodes.template.presentation.injection.viewModelModule +import org.koin.android.ext.android.inject +import org.koin.android.ext.koin.androidContext +import org.koin.core.context.startKoin -class App : DaggerApplication() { +class App : Application() { - @Inject lateinit var initializer: AppInitializer + private val initializer by inject() override fun onCreate() { super.onCreate() + startKoin { + androidContext(this@App) + modules( + viewModelModule, + appModule, + restModule, + restRepositoryModule, + storageModule, + interactorModule + ) + } initializer.init(this) } @@ -20,8 +37,4 @@ class App : DaggerApplication() { super.attachBaseContext(base) MultiDex.install(this) } - - override fun applicationInjector(): AndroidInjector { - return DaggerAppComponent.factory().create(this) - } } \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/inititializers/AppInitializer.kt b/app/src/main/java/dk/nodes/template/inititializers/AppInitializer.kt index 54b6cc0b..8c880b88 100644 --- a/app/src/main/java/dk/nodes/template/inititializers/AppInitializer.kt +++ b/app/src/main/java/dk/nodes/template/inititializers/AppInitializer.kt @@ -5,13 +5,12 @@ import dk.nodes.nstack.kotlin.NStack import dk.nodes.template.BuildConfig import dk.nodes.template.presentation.nstack.Translation import timber.log.Timber -import javax.inject.Inject interface AppInitializer { fun init(app: Application) } -class AppInitializerImpl @Inject constructor() : AppInitializer { +class AppInitializerImpl : AppInitializer { override fun init(app: Application) { NStack.translationClass = Translation::class.java NStack.init(app) diff --git a/app/src/main/java/dk/nodes/template/injection/components/AppComponent.kt b/app/src/main/java/dk/nodes/template/injection/components/AppComponent.kt deleted file mode 100644 index 9d2f6f7c..00000000 --- a/app/src/main/java/dk/nodes/template/injection/components/AppComponent.kt +++ /dev/null @@ -1,32 +0,0 @@ -package dk.nodes.template.injection.components - -import dagger.Component -import dagger.android.AndroidInjector -import dagger.android.support.AndroidSupportInjectionModule -import dk.nodes.arch.domain.injection.scopes.AppScope -import dk.nodes.template.App -import dk.nodes.template.injection.modules.AppModule -import dk.nodes.template.injection.modules.ExecutorModule -import dk.nodes.template.injection.modules.InteractorModule -import dk.nodes.template.injection.modules.RestModule -import dk.nodes.template.injection.modules.RestRepositoryBinding -import dk.nodes.template.injection.modules.StorageBindingModule -import dk.nodes.template.presentation.injection.ViewModelBuilder - -@Component( - modules = [ - AndroidSupportInjectionModule::class, - ViewModelBuilder::class, - AppModule::class, - ExecutorModule::class, - InteractorModule::class, - RestModule::class, - RestRepositoryBinding::class, - StorageBindingModule::class - ] -) -@AppScope -interface AppComponent : AndroidInjector { - @Component.Factory - abstract class Factory : AndroidInjector.Factory -} \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/AppModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/AppModule.kt deleted file mode 100644 index 70fe5365..00000000 --- a/app/src/main/java/dk/nodes/template/injection/modules/AppModule.kt +++ /dev/null @@ -1,23 +0,0 @@ -package dk.nodes.template.injection.modules - -import android.content.Context -import dagger.Binds -import dagger.Module -import dagger.Provides -import dk.nodes.template.App -import dk.nodes.template.inititializers.AppInitializer -import dk.nodes.template.inititializers.AppInitializerImpl - -@Module -abstract class AppModule { - - @Binds - abstract fun bindAppInitalizer(initializer: AppInitializerImpl): AppInitializer - - @Module - companion object { - @JvmStatic - @Provides - fun provideContext(application: App): Context = application.applicationContext - } -} \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/ExecutorModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/ExecutorModule.kt deleted file mode 100644 index b643cd59..00000000 --- a/app/src/main/java/dk/nodes/template/injection/modules/ExecutorModule.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dk.nodes.template.injection.modules - -import dagger.Module -import dagger.Provides -import dk.nodes.arch.domain.executor.Executor -import dk.nodes.arch.domain.executor.ThreadExecutor -import dk.nodes.arch.domain.injection.scopes.AppScope - -@Module -class ExecutorModule { - @Provides - @AppScope - fun provideExecutor(): Executor { - return ThreadExecutor() - } -} \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/InteractorModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/InteractorModule.kt deleted file mode 100644 index ba398d55..00000000 --- a/app/src/main/java/dk/nodes/template/injection/modules/InteractorModule.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dk.nodes.template.injection.modules - -import dagger.Module - -@Module -class InteractorModule \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/RestModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/RestModule.kt deleted file mode 100644 index 14125bb9..00000000 --- a/app/src/main/java/dk/nodes/template/injection/modules/RestModule.kt +++ /dev/null @@ -1,96 +0,0 @@ -package dk.nodes.template.injection.modules - -import com.google.gson.Gson -import com.google.gson.GsonBuilder -import dagger.Module -import dagger.Provides -import dk.nodes.arch.domain.injection.scopes.AppScope -import dk.nodes.nstack.kotlin.providers.NMetaInterceptor -import dk.nodes.template.BuildConfig -import dk.nodes.template.network.Api -import dk.nodes.template.network.util.BufferedSourceConverterFactory -import dk.nodes.template.network.util.DateDeserializer -import dk.nodes.template.network.util.ItemTypeAdapterFactory -import okhttp3.OkHttpClient -import retrofit2.Converter -import retrofit2.Retrofit -import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory -import retrofit2.converter.gson.GsonConverterFactory -import java.util.Date -import java.util.concurrent.TimeUnit -import javax.inject.Named - -@Module -class RestModule { - @Provides - fun provideTypeFactory(): ItemTypeAdapterFactory { - return ItemTypeAdapterFactory() - } - - @Provides - fun provideDateDeserializer(): DateDeserializer { - return DateDeserializer() - } - - @Provides - @AppScope - fun provideGson(typeFactory: ItemTypeAdapterFactory, dateDeserializer: DateDeserializer): Gson { - return GsonBuilder() - .registerTypeAdapterFactory(typeFactory) - .registerTypeAdapter(Date::class.java, dateDeserializer) - .setDateFormat(DateDeserializer.DATE_FORMATS[0]) - .create() - } - - @Provides - @Named("NAME_BASE_URL") - fun provideBaseUrlString(): String { - return BuildConfig.API_URL - } - - @Provides - @AppScope - fun provideGsonConverter(gson: Gson): Converter.Factory { - return GsonConverterFactory.create(gson) - } - - @Provides - @AppScope - fun provideHttpClient(): OkHttpClient { - val clientBuilder = OkHttpClient.Builder() - .connectTimeout(45, TimeUnit.SECONDS) - .readTimeout(60, TimeUnit.SECONDS) - .writeTimeout(60, TimeUnit.SECONDS) - .addInterceptor(NMetaInterceptor(BuildConfig.BUILD_TYPE)) - - if (BuildConfig.DEBUG) { - val logging = okhttp3.logging.HttpLoggingInterceptor() - logging.level = okhttp3.logging.HttpLoggingInterceptor.Level.BODY - clientBuilder.addInterceptor(logging) - } - - return clientBuilder.build() - } - - @Provides - @AppScope - fun provideRetrofit( - client: OkHttpClient, - converter: Converter.Factory, - @Named("NAME_BASE_URL") baseUrl: String - ): Retrofit { - return Retrofit.Builder() - .client(client) - .baseUrl(baseUrl) - .addConverterFactory(BufferedSourceConverterFactory()) - .addConverterFactory(converter) - .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) - .build() - } - - @Provides - @AppScope - fun provideApi(retrofit: Retrofit): Api { - return retrofit.create(Api::class.java) - } -} diff --git a/app/src/main/java/dk/nodes/template/injection/modules/RestRepositoryBinding.kt b/app/src/main/java/dk/nodes/template/injection/modules/RestRepositoryBinding.kt deleted file mode 100644 index 017dda2d..00000000 --- a/app/src/main/java/dk/nodes/template/injection/modules/RestRepositoryBinding.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dk.nodes.template.injection.modules - -import dagger.Binds -import dagger.Module -import dk.nodes.arch.domain.injection.scopes.AppScope -import dk.nodes.template.network.RestPostRepository -import dk.nodes.template.repositories.PostRepository - -@Module -abstract class RestRepositoryBinding { - @Binds - @AppScope - abstract fun bindPostRepository(repository: RestPostRepository): PostRepository -} \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/StorageBindingModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/StorageBindingModule.kt deleted file mode 100644 index bd8c0f4e..00000000 --- a/app/src/main/java/dk/nodes/template/injection/modules/StorageBindingModule.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dk.nodes.template.injection.modules - -import dagger.Binds -import dagger.Module -import dk.nodes.arch.domain.injection.scopes.AppScope -import dk.nodes.template.domain.managers.PrefManager -import dk.nodes.template.storage.PrefManagerImpl - -@Module -abstract class StorageBindingModule { - @Binds - @AppScope - abstract fun bindPrefManager(manager: PrefManagerImpl): PrefManager -} \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/appModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/appModule.kt new file mode 100644 index 00000000..3cdc06ba --- /dev/null +++ b/app/src/main/java/dk/nodes/template/injection/modules/appModule.kt @@ -0,0 +1,9 @@ +package dk.nodes.template.injection.modules + +import dk.nodes.template.inititializers.AppInitializer +import dk.nodes.template.inititializers.AppInitializerImpl +import org.koin.dsl.module + +val appModule = module { + single { AppInitializerImpl() } +} \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/restModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/restModule.kt new file mode 100644 index 00000000..2fbc8ceb --- /dev/null +++ b/app/src/main/java/dk/nodes/template/injection/modules/restModule.kt @@ -0,0 +1,62 @@ +package dk.nodes.template.injection.modules + +import com.google.gson.GsonBuilder +import com.google.gson.TypeAdapterFactory +import dk.nodes.nstack.kotlin.providers.NMetaInterceptor +import dk.nodes.template.BuildConfig +import dk.nodes.template.network.Api +import dk.nodes.template.network.util.BufferedSourceConverterFactory +import dk.nodes.template.network.util.DateDeserializer +import dk.nodes.template.network.util.ItemTypeAdapterFactory +import okhttp3.OkHttpClient +import org.koin.core.qualifier.named +import org.koin.dsl.module +import retrofit2.Converter +import retrofit2.Retrofit +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import java.util.Date +import java.util.concurrent.TimeUnit + +val restModule = module { + + factory { ItemTypeAdapterFactory() } + factory { DateDeserializer() } + single { + GsonBuilder() + .registerTypeAdapterFactory(get()) + .registerTypeAdapter(Date::class.java, get()) + .setDateFormat(DateDeserializer.DATE_FORMATS[0]) + .create() + + } + single(named("NAME_BASE_URL")) { BuildConfig.API_URL } + single { GsonConverterFactory.create(get()) } + single { + val clientBuilder = OkHttpClient.Builder() + .connectTimeout(45, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(60, TimeUnit.SECONDS) + .addInterceptor(NMetaInterceptor(BuildConfig.BUILD_TYPE)) + + if (BuildConfig.DEBUG) { + val logging = okhttp3.logging.HttpLoggingInterceptor() + logging.level = okhttp3.logging.HttpLoggingInterceptor.Level.BODY + clientBuilder.addInterceptor(logging) + } + + clientBuilder.build() + } + single { + Retrofit.Builder() + .client(get()) + .baseUrl(get(qualifier = named("NAME_BASE_URL"))) + .addConverterFactory(BufferedSourceConverterFactory()) + .addConverterFactory(get()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .build() + } + + single { get().create(Api::class.java) } + +} diff --git a/app/src/main/java/dk/nodes/template/injection/modules/restRepositoryModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/restRepositoryModule.kt new file mode 100644 index 00000000..fd3ccdf4 --- /dev/null +++ b/app/src/main/java/dk/nodes/template/injection/modules/restRepositoryModule.kt @@ -0,0 +1,9 @@ +package dk.nodes.template.injection.modules + +import dk.nodes.template.network.RestPostRepository +import dk.nodes.template.repositories.PostRepository +import org.koin.dsl.module + +val restRepositoryModule = module { + single { RestPostRepository(get()) } +} \ No newline at end of file diff --git a/app/src/main/java/dk/nodes/template/injection/modules/storageModule.kt b/app/src/main/java/dk/nodes/template/injection/modules/storageModule.kt new file mode 100644 index 00000000..1567b64a --- /dev/null +++ b/app/src/main/java/dk/nodes/template/injection/modules/storageModule.kt @@ -0,0 +1,9 @@ +package dk.nodes.template.injection.modules + +import dk.nodes.template.domain.managers.PrefManager +import dk.nodes.template.storage.PrefManagerImpl +import org.koin.dsl.module + +val storageModule = module { + single { PrefManagerImpl(get()) } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index c81a8339..51b16ed0 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,6 @@ buildscript { kotlin : '1.3.31', coroutines : '1.2.1', constraint_layout : '2.0.0-alpha4', - dagger : "2.22.1", lifecycle : "2.1.0-alpha04", hockey_sdk : "5.1.1", timber : "4.7.1", @@ -21,7 +20,8 @@ buildscript { rx_java : "2.2.8", rx_kolin : "2.3.0", ktx : "1.0.2", - rx_lint : '1.7.0' + rx_lint : '1.7.0', + koin : '2.0.0' ] ext.keys = [ diff --git a/data/build.gradle b/data/build.gradle index ac57f96f..4627de7e 100644 --- a/data/build.gradle +++ b/data/build.gradle @@ -7,5 +7,5 @@ dependencies { exclude module: "retrofit:${versions.retrofit}" } implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.coroutines}" - implementation "com.google.dagger:dagger-android:${versions.dagger}" + implementation "org.koin:koin-core:${versions.koin}" } \ No newline at end of file diff --git a/data/src/main/java/dk/nodes/template/network/RestPostRepository.kt b/data/src/main/java/dk/nodes/template/network/RestPostRepository.kt index cd96717e..97bf10e3 100644 --- a/data/src/main/java/dk/nodes/template/network/RestPostRepository.kt +++ b/data/src/main/java/dk/nodes/template/network/RestPostRepository.kt @@ -3,9 +3,8 @@ package dk.nodes.template.network import dk.nodes.template.models.Post import dk.nodes.template.repositories.PostRepository import dk.nodes.template.repositories.RepositoryException -import javax.inject.Inject -class RestPostRepository @Inject constructor(private val api: Api) : PostRepository { +class RestPostRepository(private val api: Api) : PostRepository { @Throws(RepositoryException::class) override suspend fun getPosts(cached: Boolean): List { val response = api.getPosts().execute() diff --git a/domain/build.gradle b/domain/build.gradle index 596a9452..bba76d2e 100644 --- a/domain/build.gradle +++ b/domain/build.gradle @@ -3,6 +3,6 @@ apply plugin: 'kotlin' dependencies { implementation project(':data') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}" - implementation "com.google.dagger:dagger-android:${versions.dagger}" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.coroutines}" + implementation "org.koin:koin-core:${versions.koin}" } diff --git a/domain/src/main/java/dk/nodes/template/domain/interactors/PostsInteractor.kt b/domain/src/main/java/dk/nodes/template/domain/interactors/PostsInteractor.kt index f2e8becc..cb90f1a4 100644 --- a/domain/src/main/java/dk/nodes/template/domain/interactors/PostsInteractor.kt +++ b/domain/src/main/java/dk/nodes/template/domain/interactors/PostsInteractor.kt @@ -2,11 +2,9 @@ package dk.nodes.template.domain.interactors import dk.nodes.template.models.Post import dk.nodes.template.repositories.PostRepository -import javax.inject.Inject -class PostsInteractor @Inject constructor( - private val postRepository: PostRepository -) : BaseAsyncInteractor> { +class PostsInteractor(private val postRepository: PostRepository) : + BaseAsyncInteractor> { override suspend fun invoke(): List { return postRepository.getPosts(true) diff --git a/domain/src/main/java/dk/nodes/template/domain/modules/interactorModule.kt b/domain/src/main/java/dk/nodes/template/domain/modules/interactorModule.kt new file mode 100644 index 00000000..c88df63c --- /dev/null +++ b/domain/src/main/java/dk/nodes/template/domain/modules/interactorModule.kt @@ -0,0 +1,8 @@ +package dk.nodes.template.domain.modules + +import dk.nodes.template.domain.interactors.PostsInteractor +import org.koin.dsl.module + +val interactorModule = module { + factory { PostsInteractor(get()) } +} \ No newline at end of file diff --git a/presentation/build.gradle b/presentation/build.gradle index a505f77d..0811fe87 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -44,10 +44,10 @@ dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.lifecycle}" kapt "androidx.lifecycle:lifecycle-compiler:${versions.lifecycle}" implementation "androidx.core:core-ktx:${versions.ktx}" - implementation "com.google.dagger:dagger-android:${versions.dagger}" - implementation "com.google.dagger:dagger-android-support:${versions.dagger}" - kapt "com.google.dagger:dagger-compiler:${versions.dagger}" - kapt "com.google.dagger:dagger-android-processor:${versions.dagger}" + implementation "org.koin:koin-core:${versions.koin}" + implementation "org.koin:koin-android-scope:${versions.koin}" + implementation "org.koin:koin-android-viewmodel:${versions.koin}" + implementation "org.koin:koin-android-ext:${versions.koin}" implementation 'dk.nodes.nstack:nstack-kotlin:2.2.0' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.coroutines}" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.coroutines}" diff --git a/presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt b/presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt index 8bd13a2c..fedc9d5a 100644 --- a/presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt +++ b/presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt @@ -1,76 +1,76 @@ package dk.nodes.template.presentation.extensions -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.OnLifecycleEvent -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelProviders +//import androidx.fragment.app.Fragment +//import androidx.fragment.app.FragmentActivity +//import androidx.lifecycle.Lifecycle +//import androidx.lifecycle.LifecycleObserver +//import androidx.lifecycle.LifecycleOwner +//import androidx.lifecycle.OnLifecycleEvent +//import androidx.lifecycle.ViewModel +//import androidx.lifecycle.ViewModelProvider +//import androidx.lifecycle.ViewModelProviders import java.io.Serializable -inline fun LifecycleOwner.getViewModel(factory: ViewModelProvider.Factory): VM { - return when (this) { - is Fragment -> ViewModelProviders.of(this, factory).get(VM::class.java) - is FragmentActivity -> ViewModelProviders.of(this, factory).get(VM::class.java) - else -> throw IllegalAccessError("Invalid LifecycleOwner") - } -} - -inline fun Fragment.getSharedViewModel(factory: ViewModelProvider.Factory): VM { - return ViewModelProviders.of(requireActivity(), factory).get(VM::class.java) -} - -private object UninitializedValue - -/** - * This was copied from SynchronizedLazyImpl but modified to automatically initialize in ON_CREATE. - */ -@Suppress("ClassName") -class lifecycleAwareLazy(private val owner: LifecycleOwner, initializer: () -> T) : Lazy, - Serializable { - private var initializer: (() -> T)? = initializer - @Volatile - private var _value: Any? = UninitializedValue - // final field is required to enable safe publication of constructed instance - private val lock = this - - init { - owner.lifecycle.addObserver(object : LifecycleObserver { - @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) - fun onStart() { - if (!isInitialized()) value - owner.lifecycle.removeObserver(this) - } - }) - } - - @Suppress("LocalVariableName") - override val value: T - get() { - val _v1 = _value - if (_v1 !== UninitializedValue) { - @Suppress("UNCHECKED_CAST") - return _v1 as T - } - - return synchronized(lock) { - val _v2 = _value - if (_v2 !== UninitializedValue) { - @Suppress("UNCHECKED_CAST") (_v2 as T) - } else { - val typedValue = initializer!!() - _value = typedValue - initializer = null - typedValue - } - } - } - - override fun isInitialized(): Boolean = _value !== UninitializedValue - - override fun toString(): String = - if (isInitialized()) value.toString() else "Lazy value not initialized yet." -} \ No newline at end of file +//inline fun LifecycleOwner.getViewModel(factory: ViewModelProvider.Factory): VM { +// return when (this) { +// is Fragment -> ViewModelProviders.of(this, factory).get(VM::class.java) +// is FragmentActivity -> ViewModelProviders.of(this, factory).get(VM::class.java) +// else -> throw IllegalAccessError("Invalid LifecycleOwner") +// } +//} +// +//inline fun Fragment.getSharedViewModel(factory: ViewModelProvider.Factory): VM { +// return ViewModelProviders.of(requireActivity(), factory).get(VM::class.java) +//} +// +//private object UninitializedValue +// +///** +// * This was copied from SynchronizedLazyImpl but modified to automatically initialize in ON_CREATE. +// */ +//@Suppress("ClassName") +//class lifecycleAwareLazy(private val owner: LifecycleOwner, initializer: () -> T) : Lazy, +// Serializable { +// private var initializer: (() -> T)? = initializer +// @Volatile +// private var _value: Any? = UninitializedValue +// // final field is required to enable safe publication of constructed instance +// private val lock = this +// +// init { +// owner.lifecycle.addObserver(object : LifecycleObserver { +// @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) +// fun onStart() { +// if (!isInitialized()) value +// owner.lifecycle.removeObserver(this) +// } +// }) +// } +// +// @Suppress("LocalVariableName") +// override val value: T +// get() { +// val _v1 = _value +// if (_v1 !== UninitializedValue) { +// @Suppress("UNCHECKED_CAST") +// return _v1 as T +// } +// +// return synchronized(lock) { +// val _v2 = _value +// if (_v2 !== UninitializedValue) { +// @Suppress("UNCHECKED_CAST") (_v2 as T) +// } else { +// val typedValue = initializer!!() +// _value = typedValue +// initializer = null +// typedValue +// } +// } +// } +// +// override fun isInitialized(): Boolean = _value !== UninitializedValue +// +// override fun toString(): String = +// if (isInitialized()) value.toString() else "Lazy value not initialized yet." +//} \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/injection/DaggerViewModelFactory.kt b/presentation/src/main/java/dk/nodes/template/presentation/injection/DaggerViewModelFactory.kt deleted file mode 100644 index 5469408c..00000000 --- a/presentation/src/main/java/dk/nodes/template/presentation/injection/DaggerViewModelFactory.kt +++ /dev/null @@ -1,31 +0,0 @@ -package dk.nodes.template.presentation.injection - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import javax.inject.Inject -import javax.inject.Provider - -internal class DaggerViewModelFactory @Inject constructor( - private val creators: @JvmSuppressWildcards Map, Provider> -) : ViewModelProvider.Factory { - override fun create(modelClass: Class): T { - var creator: Provider? = creators[modelClass] - if (creator == null) { - for ((key, value) in creators) { - if (modelClass.isAssignableFrom(key)) { - creator = value - break - } - } - } - if (creator == null) { - throw IllegalArgumentException("Unknown model class: $modelClass") - } - try { - @Suppress("UNCHECKED_CAST") - return creator.get() as T - } catch (e: Exception) { - throw RuntimeException(e) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelBuilder.kt b/presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelBuilder.kt deleted file mode 100644 index 772881e2..00000000 --- a/presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelBuilder.kt +++ /dev/null @@ -1,17 +0,0 @@ -package dk.nodes.template.presentation.injection - -import androidx.lifecycle.ViewModelProvider -import dagger.Binds -import dagger.Module -import dk.nodes.template.presentation.ui.main.MainActivityBuilder - -@Module( - includes = [ - MainActivityBuilder::class - ] -) -abstract class ViewModelBuilder { - - @Binds - internal abstract fun bindViewModelFactory(factory: DaggerViewModelFactory): ViewModelProvider.Factory -} \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelKey.kt b/presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelKey.kt deleted file mode 100644 index 965c9ba0..00000000 --- a/presentation/src/main/java/dk/nodes/template/presentation/injection/ViewModelKey.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dk.nodes.template.presentation.injection - -import androidx.lifecycle.ViewModel -import dagger.MapKey -import kotlin.reflect.KClass - -@Target( - AnnotationTarget.FUNCTION, - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.PROPERTY_SETTER -) -@Retention(AnnotationRetention.RUNTIME) -@MapKey -annotation class ViewModelKey(val value: KClass) \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/injection/viewModelModule.kt b/presentation/src/main/java/dk/nodes/template/presentation/injection/viewModelModule.kt new file mode 100644 index 00000000..b0c60c8a --- /dev/null +++ b/presentation/src/main/java/dk/nodes/template/presentation/injection/viewModelModule.kt @@ -0,0 +1,9 @@ +package dk.nodes.template.presentation.injection + +import dk.nodes.template.presentation.ui.main.mainActivityModule +import org.koin.core.context.loadKoinModules +import org.koin.dsl.module + +val viewModelModule = module { + loadKoinModules(mainActivityModule) +} \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseActivity.kt b/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseActivity.kt index 0c9efa10..2d92e72a 100644 --- a/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseActivity.kt +++ b/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseActivity.kt @@ -1,26 +1,12 @@ package dk.nodes.template.presentation.ui.base import android.content.Context -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import dagger.android.support.DaggerAppCompatActivity +import androidx.appcompat.app.AppCompatActivity import dk.nodes.nstack.kotlin.inflater.NStackBaseContext -import dk.nodes.template.presentation.extensions.getViewModel -import dk.nodes.template.presentation.extensions.lifecycleAwareLazy -import javax.inject.Inject -abstract class BaseActivity : DaggerAppCompatActivity() { - - @Inject lateinit var viewModelFactory: ViewModelProvider.Factory +abstract class BaseActivity : AppCompatActivity() { override fun attachBaseContext(newBase: Context) { super.attachBaseContext(NStackBaseContext(newBase)) } - - protected inline fun getViewModel(): VM = - getViewModel(viewModelFactory) - - protected inline fun viewModel(): Lazy { - return lifecycleAwareLazy(this) { getViewModel() } - } } \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseFragment.kt b/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseFragment.kt index 178d8d26..dde17101 100644 --- a/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseFragment.kt +++ b/presentation/src/main/java/dk/nodes/template/presentation/ui/base/BaseFragment.kt @@ -1,28 +1,5 @@ package dk.nodes.template.presentation.ui.base -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import dagger.android.support.DaggerFragment -import dk.nodes.template.presentation.extensions.getSharedViewModel -import dk.nodes.template.presentation.extensions.getViewModel -import dk.nodes.template.presentation.extensions.lifecycleAwareLazy -import javax.inject.Inject +import androidx.fragment.app.Fragment -abstract class BaseFragment : DaggerFragment() { - @Inject lateinit var viewModelFactory: ViewModelProvider.Factory - - protected inline fun getViewModel(): VM = - getViewModel(viewModelFactory) - - protected inline fun getSharedViewModel(): VM = - getSharedViewModel(viewModelFactory) - - protected inline fun viewModel(): Lazy = lifecycleAwareLazy(this) { - getViewModel() - } - - protected inline fun sharedViewModel(): Lazy = - lifecycleAwareLazy(this) { - getSharedViewModel() - } -} +abstract class BaseFragment : Fragment() \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivity.kt index e35fcc47..6aa67acf 100644 --- a/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivity.kt @@ -9,6 +9,7 @@ import dk.nodes.template.presentation.nstack.Translation import dk.nodes.template.presentation.ui.base.BaseActivity import kotlinx.android.synthetic.main.activity_main.* import net.hockeyapp.android.UpdateManager +import org.koin.android.viewmodel.ext.android.viewModel class MainActivity : BaseActivity() { diff --git a/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityBuilder.kt b/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityBuilder.kt deleted file mode 100644 index 8d91c1fe..00000000 --- a/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityBuilder.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dk.nodes.template.presentation.ui.main - -import androidx.lifecycle.ViewModel -import dagger.Binds -import dagger.Module -import dagger.android.ContributesAndroidInjector -import dagger.multibindings.IntoMap -import dk.nodes.template.presentation.injection.ViewModelKey - -@Module -internal abstract class MainActivityBuilder { - - @Binds - @IntoMap - @ViewModelKey(MainActivityViewModel::class) - abstract fun bindMainActivityViewMode(viewModel: MainActivityViewModel): ViewModel - - @ContributesAndroidInjector - internal abstract fun mainActivity(): MainActivity -} \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityModule.kt b/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityModule.kt new file mode 100644 index 00000000..c325229b --- /dev/null +++ b/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityModule.kt @@ -0,0 +1,8 @@ +package dk.nodes.template.presentation.ui.main + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module + +val mainActivityModule = module { + viewModel { MainActivityViewModel(get()) } +} \ No newline at end of file diff --git a/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityViewModel.kt b/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityViewModel.kt index e89ac884..f76fba98 100644 --- a/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityViewModel.kt +++ b/presentation/src/main/java/dk/nodes/template/presentation/ui/main/MainActivityViewModel.kt @@ -20,11 +20,8 @@ import dk.nodes.template.presentation.ui.base.BaseViewModel import dk.nodes.template.presentation.ui.base.scope import dk.nodes.template.presentation.util.SingleEvent import kotlinx.coroutines.launch -import javax.inject.Inject -class MainActivityViewModel @Inject constructor( - postsInteractor: PostsInteractor -) : BaseViewModel() { +class MainActivityViewModel(postsInteractor: PostsInteractor) : BaseViewModel() { private val liveDataInteractor = postsInteractor.asLiveData() private val resultInteractor = postsInteractor.asResult() From 90a07fe171732e63f090d1019a8977ddfc714c68 Mon Sep 17 00:00:00 2001 From: lucassales Date: Tue, 28 May 2019 11:04:02 +0200 Subject: [PATCH 2/3] Delete LifecycleOwnerExtensions.kt --- .../extensions/LifecycleOwnerExtensions.kt | 76 ------------------- 1 file changed, 76 deletions(-) delete mode 100644 presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt diff --git a/presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt b/presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt deleted file mode 100644 index fedc9d5a..00000000 --- a/presentation/src/main/java/dk/nodes/template/presentation/extensions/LifecycleOwnerExtensions.kt +++ /dev/null @@ -1,76 +0,0 @@ -package dk.nodes.template.presentation.extensions - -//import androidx.fragment.app.Fragment -//import androidx.fragment.app.FragmentActivity -//import androidx.lifecycle.Lifecycle -//import androidx.lifecycle.LifecycleObserver -//import androidx.lifecycle.LifecycleOwner -//import androidx.lifecycle.OnLifecycleEvent -//import androidx.lifecycle.ViewModel -//import androidx.lifecycle.ViewModelProvider -//import androidx.lifecycle.ViewModelProviders -import java.io.Serializable - -//inline fun LifecycleOwner.getViewModel(factory: ViewModelProvider.Factory): VM { -// return when (this) { -// is Fragment -> ViewModelProviders.of(this, factory).get(VM::class.java) -// is FragmentActivity -> ViewModelProviders.of(this, factory).get(VM::class.java) -// else -> throw IllegalAccessError("Invalid LifecycleOwner") -// } -//} -// -//inline fun Fragment.getSharedViewModel(factory: ViewModelProvider.Factory): VM { -// return ViewModelProviders.of(requireActivity(), factory).get(VM::class.java) -//} -// -//private object UninitializedValue -// -///** -// * This was copied from SynchronizedLazyImpl but modified to automatically initialize in ON_CREATE. -// */ -//@Suppress("ClassName") -//class lifecycleAwareLazy(private val owner: LifecycleOwner, initializer: () -> T) : Lazy, -// Serializable { -// private var initializer: (() -> T)? = initializer -// @Volatile -// private var _value: Any? = UninitializedValue -// // final field is required to enable safe publication of constructed instance -// private val lock = this -// -// init { -// owner.lifecycle.addObserver(object : LifecycleObserver { -// @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) -// fun onStart() { -// if (!isInitialized()) value -// owner.lifecycle.removeObserver(this) -// } -// }) -// } -// -// @Suppress("LocalVariableName") -// override val value: T -// get() { -// val _v1 = _value -// if (_v1 !== UninitializedValue) { -// @Suppress("UNCHECKED_CAST") -// return _v1 as T -// } -// -// return synchronized(lock) { -// val _v2 = _value -// if (_v2 !== UninitializedValue) { -// @Suppress("UNCHECKED_CAST") (_v2 as T) -// } else { -// val typedValue = initializer!!() -// _value = typedValue -// initializer = null -// typedValue -// } -// } -// } -// -// override fun isInitialized(): Boolean = _value !== UninitializedValue -// -// override fun toString(): String = -// if (isInitialized()) value.toString() else "Lazy value not initialized yet." -//} \ No newline at end of file From 532670e732ed760d3c85e5db2d0863e31200c4d9 Mon Sep 17 00:00:00 2001 From: lucassales Date: Fri, 7 Jun 2019 11:54:43 +0200 Subject: [PATCH 3/3] Updating koin --- app/src/main/java/dk/nodes/template/App.kt | 10 +++++----- build.gradle | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/dk/nodes/template/App.kt b/app/src/main/java/dk/nodes/template/App.kt index 226735ae..b30b9c1e 100644 --- a/app/src/main/java/dk/nodes/template/App.kt +++ b/app/src/main/java/dk/nodes/template/App.kt @@ -22,11 +22,11 @@ class App : Application() { startKoin { androidContext(this@App) modules( - viewModelModule, - appModule, - restModule, - restRepositoryModule, - storageModule, + viewModelModule + + appModule + + restModule + + restRepositoryModule + + storageModule + interactorModule ) } diff --git a/build.gradle b/build.gradle index 5f620c5d..abb0cf2a 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { ktx : "1.0.2", rx_lint : '1.7.0', material : '1.1.0-alpha07', - koin : '2.0.0' + koin : '2.0.1' ] ext.keys = [