1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

App | Tech | Dagger Component instead of Subcomponent PoC (#2180)

Co-authored-by: Mikhail Iudin <mayudin@anytype.io>
This commit is contained in:
Mikhail 2022-04-21 16:25:53 +03:00 committed by GitHub
parent 1f23c64387
commit d41be27bbb
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 96 additions and 38 deletions

View file

@ -9,7 +9,9 @@ import com.anytypeio.anytype.BuildConfig
import com.anytypeio.anytype.R
import com.anytypeio.anytype.analytics.tracker.AmplitudeTracker
import com.anytypeio.anytype.core_utils.tools.CrashlyticsTree
import com.anytypeio.anytype.di.common.ComponentDependenciesProvider
import com.anytypeio.anytype.di.common.ComponentManager
import com.anytypeio.anytype.di.common.HasComponentDependencies
import com.anytypeio.anytype.di.main.ContextModule
import com.anytypeio.anytype.di.main.DaggerMainComponent
import com.anytypeio.anytype.di.main.MainComponent
@ -17,7 +19,7 @@ import com.anytypeio.anytype.middleware.interactor.LocalNetworkAddressHandler
import timber.log.Timber
import javax.inject.Inject
class AndroidApplication : Application() {
class AndroidApplication : Application(), HasComponentDependencies {
@Inject
lateinit var amplitudeTracker: AmplitudeTracker
@ -25,6 +27,10 @@ class AndroidApplication : Application() {
@Inject
lateinit var localNetworkAddressHandler: LocalNetworkAddressHandler
@Inject
override lateinit var dependencies: ComponentDependenciesProvider
protected set
private val main: MainComponent by lazy {
DaggerMainComponent
.builder()
@ -33,7 +39,7 @@ class AndroidApplication : Application() {
}
val componentManager by lazy {
ComponentManager(main)
ComponentManager(main, this)
}
override fun onCreate() {

View file

@ -0,0 +1,17 @@
package com.anytypeio.anytype.di.common
import dagger.MapKey
import kotlin.reflect.KClass
interface ComponentDependencies
typealias ComponentDependenciesProvider = Map<Class<out ComponentDependencies>,
@JvmSuppressWildcards ComponentDependencies>
interface HasComponentDependencies {
val dependencies: ComponentDependenciesProvider
}
@MapKey
@Target(AnnotationTarget.FUNCTION)
annotation class ComponentDependenciesKey(val value: KClass<out ComponentDependencies>)

View file

@ -13,13 +13,16 @@ import com.anytypeio.anytype.di.feature.sets.viewer.ViewerCardSizeSelectModule
import com.anytypeio.anytype.di.feature.sets.viewer.ViewerImagePreviewSelectModule
import com.anytypeio.anytype.di.feature.settings.AboutAppModule
import com.anytypeio.anytype.di.feature.settings.AccountAndDataModule
import com.anytypeio.anytype.di.feature.settings.AppearanceModule
import com.anytypeio.anytype.di.feature.settings.DaggerAppearanceComponent
import com.anytypeio.anytype.di.feature.settings.LogoutWarningModule
import com.anytypeio.anytype.di.feature.settings.MainSettingsModule
import com.anytypeio.anytype.di.feature.wallpaper.WallpaperSelectModule
import com.anytypeio.anytype.di.main.MainComponent
class ComponentManager(private val main: MainComponent) {
class ComponentManager(
private val main: MainComponent,
private val provider: HasComponentDependencies
) {
val mainEntryComponent = Component {
main.mainEntryComponentBuilder().module(MainEntryModule).build()
@ -670,10 +673,6 @@ class ComponentManager(private val main: MainComponent) {
main.accountAndDataComponent().module(AccountAndDataModule).build()
}
val appearanceComponent = Component {
main.appearanceComponent().module(AppearanceModule).build()
}
val logoutWarningComponent = Component {
main.logoutWarningComponent().module(LogoutWarningModule).build()
}
@ -682,6 +681,12 @@ class ComponentManager(private val main: MainComponent) {
main.mainSettingsComponent().module(MainSettingsModule).build()
}
val appearanceComponent = Component {
DaggerAppearanceComponent
.factory()
.create(findComponentDependencies())
}
class Component<T>(private val builder: () -> T) {
private var instance: T? = null
@ -720,4 +725,8 @@ class ComponentManager(private val main: MainComponent) {
map.remove(id)
}
}
private inline fun <reified T : ComponentDependencies> findComponentDependencies(): T {
return provider.dependencies[T::class.java] as T
}
}

View file

@ -1,25 +1,33 @@
package com.anytypeio.anytype.di.feature.settings
import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
import com.anytypeio.anytype.di.common.ComponentDependencies
import com.anytypeio.anytype.domain.config.UserSettingsRepository
import com.anytypeio.anytype.domain.theme.GetTheme
import com.anytypeio.anytype.domain.theme.SetTheme
import com.anytypeio.anytype.ui.settings.AppearanceFragment
import com.anytypeio.anytype.ui_settings.appearance.AppearanceViewModel
import dagger.Component
import com.anytypeio.anytype.ui_settings.appearance.ThemeApplicator
import com.anytypeio.anytype.ui_settings.appearance.ThemeApplicatorImpl
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.Subcomponent
@Subcomponent(modules = [AppearanceModule::class])
@Component(
dependencies = [AppearanceDependencies::class],
modules = [
AppearanceModule::class,
AppearanceModule.Declarations::class
]
)
@PerScreen
interface AppearanceSubComponent {
interface AppearanceComponent {
@Subcomponent.Builder
interface Builder {
fun module(module: AppearanceModule): Builder
fun build(): AppearanceSubComponent
@Component.Factory
interface Factory {
fun create(dependencies: AppearanceDependencies): AppearanceComponent
}
fun inject(fragment: AppearanceFragment)
@ -27,23 +35,6 @@ interface AppearanceSubComponent {
@Module
object AppearanceModule {
@JvmStatic
@Provides
@PerScreen
fun provideViewModelFactory(
getTheme: GetTheme,
setTheme: SetTheme,
themeApplicator: ThemeApplicator
): AppearanceViewModel.Factory = AppearanceViewModel.Factory(
getTheme,
setTheme,
themeApplicator
)
@JvmStatic
@PerScreen
@Provides
fun provideThemeApplicator(): ThemeApplicator = ThemeApplicatorImpl()
@JvmStatic
@Provides
@ -54,4 +45,22 @@ object AppearanceModule {
@Provides
@PerScreen
fun provideSetThemeUseCase(repo: UserSettingsRepository): SetTheme = SetTheme(repo)
@Module
interface Declarations {
@PerScreen
@Binds
fun bindViewModelFactory(
factory: AppearanceViewModel.Factory
): ViewModelProvider.Factory
@PerScreen
@Binds
fun bindThemeApplicator(applicator: ThemeApplicatorImpl): ThemeApplicator
}
}
interface AppearanceDependencies : ComponentDependencies {
fun userUserSettingsRepository(): UserSettingsRepository
}

View file

@ -1,20 +1,26 @@
package com.anytypeio.anytype.di.main
import com.anytypeio.anytype.app.AndroidApplication
import com.anytypeio.anytype.di.common.ComponentDependencies
import com.anytypeio.anytype.di.common.ComponentDependenciesKey
import com.anytypeio.anytype.di.feature.*
import com.anytypeio.anytype.di.feature.auth.DeletedAccountSubcomponent
import com.anytypeio.anytype.di.feature.settings.AboutAppSubComponent
import com.anytypeio.anytype.di.feature.settings.AccountAndDataSubComponent
import com.anytypeio.anytype.di.feature.settings.AppearanceSubComponent
import com.anytypeio.anytype.di.feature.settings.AppearanceDependencies
import com.anytypeio.anytype.di.feature.settings.LogoutWarningSubComponent
import com.anytypeio.anytype.di.feature.settings.MainSettingsSubComponent
import com.anytypeio.anytype.di.feature.wallpaper.WallpaperSelectSubComponent
import dagger.Binds
import dagger.Component
import dagger.Module
import dagger.multibindings.IntoMap
import javax.inject.Singleton
@Singleton
@Component(
modules = [
ComponentDependenciesModule::class,
ContextModule::class,
DataModule::class,
EventModule::class,
@ -27,7 +33,7 @@ import javax.inject.Singleton
LocalNetworkAddressModule::class
]
)
interface MainComponent {
interface MainComponent : AppearanceDependencies {
fun inject(app: AndroidApplication)
fun splashComponentBuilder(): SplashSubComponent.Builder
@ -60,7 +66,6 @@ interface MainComponent {
fun aboutAppComponent() : AboutAppSubComponent.Builder
fun accountAndDataComponent() : AccountAndDataSubComponent.Builder
fun appearanceComponent() : AppearanceSubComponent.Builder
fun debugSettingsBuilder(): DebugSettingsSubComponent.Builder
fun keychainPhraseComponentBuilder(): KeychainPhraseSubComponent.Builder
fun otherSettingsComponentBuilder(): OtherSettingsSubComponent.Builder
@ -68,4 +73,13 @@ interface MainComponent {
fun mainSettingsComponent() : MainSettingsSubComponent.Builder
//endregion
}
@Module
private abstract class ComponentDependenciesModule private constructor() {
@Binds
@IntoMap
@ComponentDependenciesKey(AppearanceDependencies::class)
abstract fun provideAppearanceDependencies (component: MainComponent): ComponentDependencies
}

View file

@ -2,7 +2,6 @@ package com.anytypeio.anytype.domain.theme
import com.anytypeio.anytype.core_models.ThemeMode
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.config.UserSettingsRepository
class GetTheme(

View file

@ -37,6 +37,8 @@ dependencies {
def applicationDependencies = rootProject.ext.mainApplication
def unitTestDependencies = rootProject.ext.unitTesting
compileOnly applicationDependencies.javaxInject
implementation applicationDependencies.lifecycleViewModel
implementation applicationDependencies.lifecycleRuntime

View file

@ -10,6 +10,7 @@ import com.anytypeio.anytype.domain.theme.SetTheme
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class AppearanceViewModel(
private val getTheme: GetTheme,
@ -65,7 +66,7 @@ class AppearanceViewModel(
selectedTheme.value = themeMode
}
class Factory(
class Factory @Inject constructor(
private val getTheme: GetTheme,
private val setTheme: SetTheme,
private val themeApplicator: ThemeApplicator,

View file

@ -2,6 +2,7 @@ package com.anytypeio.anytype.ui_settings.appearance
import androidx.appcompat.app.AppCompatDelegate
import com.anytypeio.anytype.core_models.ThemeMode
import javax.inject.Inject
interface ThemeApplicator {
@ -9,7 +10,7 @@ interface ThemeApplicator {
}
class ThemeApplicatorImpl: ThemeApplicator {
class ThemeApplicatorImpl @Inject constructor(): ThemeApplicator {
override fun apply(theme: ThemeMode) {
when(theme) {
ThemeMode.Light -> apply(AppCompatDelegate.MODE_NIGHT_NO)