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:
parent
1f23c64387
commit
d41be27bbb
9 changed files with 96 additions and 38 deletions
|
@ -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() {
|
||||
|
|
|
@ -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>)
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -37,6 +37,8 @@ dependencies {
|
|||
def applicationDependencies = rootProject.ext.mainApplication
|
||||
def unitTestDependencies = rootProject.ext.unitTesting
|
||||
|
||||
compileOnly applicationDependencies.javaxInject
|
||||
|
||||
implementation applicationDependencies.lifecycleViewModel
|
||||
implementation applicationDependencies.lifecycleRuntime
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue