Skip to content
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
4 changes: 1 addition & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.compose'
id 'com.google.devtools.ksp'
}

android {
Expand Down Expand Up @@ -55,8 +54,7 @@ dependencies {

implementation libs.bundles.decompose

implementation libs.dagger.core
ksp libs.dagger.compiler
implementation libs.koin.android

implementation project(':ui')
implementation project(':feature-root')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import com.alaershov.mars_colony.root.RootComponent
import com.alaershov.mars_colony.root.RootScreen
import com.alaershov.mars_colony.ui.theme.MarsColonyTheme
import com.arkivanov.decompose.defaultComponentContext
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
import com.alaershov.mars_colony.root.di.rootKoinModule
import com.alaershov.mars_colony.dashboard.di.dashboardKoinModule
import com.alaershov.mars_colony.habitat.di.habitatKoinModule
import com.alaershov.mars_colony.power.di.powerKoinModule
import com.alaershov.mars_colony.message_dialog.di.messageDialogKoinModule
import com.alaershov.mars_colony.shared.weather.di.weatherKoinModule
import org.koin.java.KoinJavaComponent.getKoin

/**
* Единственное Activity, которое является точкой входа в приложение.
Expand All @@ -19,13 +28,24 @@ class MarsColonyAppActivity : ComponentActivity() {

enableEdgeToEdge()

// Единственное место, где мы создаём и напрямую используем Dagger компонент
// для того, чтобы создать корневой Decompose-компонент.
val component: RootComponent = DaggerMarsColonyAppDiComponent.create()
.rootComponentFactory
.create(
componentContext = defaultComponentContext(),
startKoin {
androidContext(this@MarsColonyAppActivity)
modules(
rootKoinModule,
dashboardKoinModule,
habitatKoinModule,
powerKoinModule,
messageDialogKoinModule,
weatherKoinModule,
)
}

val rootFactory: com.alaershov.mars_colony.root.RootComponent.Factory =
getKoin().get()

val component: RootComponent = rootFactory.create(
componentContext = defaultComponentContext(),
)

setContent {
MarsColonyTheme {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,3 @@
package com.alaershov.mars_colony.app

import com.alaershov.mars_colony.dashboard.di.DashboardComponentDiModule
import com.alaershov.mars_colony.habitat.di.HabitatComponentDiModule
import com.alaershov.mars_colony.habitat.di.HabitatRepositoryDiModule
import com.alaershov.mars_colony.message_dialog.di.MessageDialogComponentDiModule
import com.alaershov.mars_colony.power.PowerPlantRepositoryDiModule
import com.alaershov.mars_colony.power.di.PowerComponentDiModule
import com.alaershov.mars_colony.root.RootComponent
import com.alaershov.mars_colony.root.di.RootComponentDiModule
import com.alaershov.mars_colony.shared.weather.di.WeatherDiModule
import dagger.Component
import javax.inject.Singleton

/**
* Единственный Dagger-компонент приложения.
*
* В него подключаются все Dagger-модули, которые предоставляют
* feature-модули приложения.
*
* В этих Dagger-модулях могут быть описаны как фабрики создания
* Decompose-компонентов, так и любые другие зависимости -
* репозитории, интеракторы, и прочее.
*
* В feature-модулях нет нужны объявлять собственные Dagger-компоненты.
*/
@Singleton
@Component(
modules = [
RootComponentDiModule::class,
DashboardComponentDiModule::class,
HabitatComponentDiModule::class,
PowerComponentDiModule::class,
MessageDialogComponentDiModule::class,
HabitatRepositoryDiModule::class,
PowerPlantRepositoryDiModule::class,
WeatherDiModule::class,
]
)
interface MarsColonyAppDiComponent {

val rootComponentFactory: RootComponent.Factory
}
// Removed Dagger component; Koin will be used for DI
4 changes: 1 addition & 3 deletions feature-dashboard/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.compose'
id 'com.google.devtools.ksp'
}

android {
Expand Down Expand Up @@ -38,8 +37,7 @@ dependencies {

implementation libs.bundles.decompose

implementation libs.dagger.core
ksp libs.dagger.compiler
implementation libs.koin.core

implementation project(':ui')
implementation project(':bottom-sheet')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import com.alaershov.mars_colony.power.PowerPlantRepository
import com.alaershov.mars_colony.power.totalPower
import com.alaershov.mars_colony.shared.weather.WeatherRepository
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
Expand All @@ -23,15 +20,12 @@ import kotlinx.coroutines.launch
// Обратите внимание на internal constructor
// этот компонент можно создать через фабрику,
// но нельзя из другого модуля напрямую вызвать конструктор.
class DefaultDashboardScreenComponent @AssistedInject internal constructor(
class DefaultDashboardScreenComponent internal constructor(
// сначала объявлены "аргументы"
// они передаются в фабрику компонента
// и подставляются сюда через Assisted Inject
@Assisted
componentContext: ComponentContext,
@Assisted("navigateToHabitatList")
private val navigateToHabitatList: () -> Unit,
@Assisted("navigateToPowerPlantList")
private val navigateToPowerPlantList: () -> Unit,

// ниже идут зависимости
Expand Down Expand Up @@ -88,24 +82,4 @@ class DefaultDashboardScreenComponent @AssistedInject internal constructor(
// TODO обновить
}
}

/**
* Интерфейс фабрики для AssistedInject через Dagger.
*
* Он реализует интерфейс фабрики из интерфейса компонента,
* и связывается с ним в DashboardComponentModule.
*/
@AssistedFactory
interface Factory : DashboardScreenComponent.Factory {
override fun create(
componentContext: ComponentContext,
// Аннотации @Assisted("name") нужны, чтобы разрулить
// зависимости с одинаковым типом, но разными именами.
// Аналогично работает @Named("name") в обычном графе зависимостей.
@Assisted("navigateToHabitatList")
navigateToHabitatList: () -> Unit,
@Assisted("navigateToPowerPlantList")
navigateToPowerPlantList: () -> Unit,
): DefaultDashboardScreenComponent
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@ package com.alaershov.mars_colony.dashboard.di

import com.alaershov.mars_colony.dashboard.component.DashboardScreenComponent
import com.alaershov.mars_colony.dashboard.component.DefaultDashboardScreenComponent
import dagger.Binds
import dagger.Module
import org.koin.core.module.Module
import org.koin.dsl.module

@Module
interface DashboardComponentDiModule {

@Binds
fun componentFactory(impl: DefaultDashboardScreenComponent.Factory): DashboardScreenComponent.Factory
val dashboardKoinModule: Module = module {
factory<DashboardScreenComponent.Factory> {
object : DashboardScreenComponent.Factory {
override fun create(
componentContext: com.arkivanov.decompose.ComponentContext,
navigateToHabitatList: () -> Unit,
navigateToPowerPlantList: () -> Unit,
): DashboardScreenComponent {
return DefaultDashboardScreenComponent(
componentContext = componentContext,
navigateToHabitatList = navigateToHabitatList,
navigateToPowerPlantList = navigateToPowerPlantList,
habitatRepository = get(),
powerPlantRepository = get(),
weatherRepository = get(),
)
}
}
}
}
4 changes: 1 addition & 3 deletions feature-habitat/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ plugins {
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.compose'
id 'org.jetbrains.kotlin.plugin.serialization'
id 'com.google.devtools.ksp'
}

android {
Expand Down Expand Up @@ -39,8 +38,7 @@ dependencies {

implementation libs.bundles.decompose

implementation libs.dagger.core
ksp libs.dagger.compiler
implementation libs.koin.core

implementation project(':ui')
implementation project(':bottom-sheet')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@ package com.alaershov.mars_colony.habitat.build_dialog
import com.alaershov.mars_colony.bottom_sheet.BottomSheetContentState
import com.alaershov.mars_colony.habitat.HabitatRepository
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class DefaultHabitatBuildDialogComponent @AssistedInject internal constructor(
@Assisted
class DefaultHabitatBuildDialogComponent internal constructor(
componentContext: ComponentContext,
@Assisted("onDismiss")
private val onDismiss: () -> Unit,
private val habitatRepository: HabitatRepository,
) : HabitatBuildDialogComponent, ComponentContext by componentContext {
Expand Down Expand Up @@ -63,13 +58,4 @@ class DefaultHabitatBuildDialogComponent @AssistedInject internal constructor(
onDismiss()
}
}

@AssistedFactory
interface Factory : HabitatBuildDialogComponent.Factory {
override fun create(
componentContext: ComponentContext,
@Assisted("onDismiss")
onDismiss: () -> Unit
): DefaultHabitatBuildDialogComponent
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,83 @@
package com.alaershov.mars_colony.habitat.di

import com.alaershov.mars_colony.habitat.build_dialog.DefaultHabitatBuildDialogComponent
import com.alaershov.mars_colony.habitat.HabitatRepository
import com.alaershov.mars_colony.habitat.build_dialog.HabitatBuildDialogComponent
import com.alaershov.mars_colony.habitat.build_dialog.DefaultHabitatBuildDialogComponent
import com.alaershov.mars_colony.habitat.dismantle_dialog.component.DefaultHabitatDismantleDialogComponent
import com.alaershov.mars_colony.habitat.dismantle_dialog.component.HabitatDismantleDialogComponent
import com.alaershov.mars_colony.habitat.info_screen.DefaultHabitatInfoScreenComponent
import com.alaershov.mars_colony.habitat.info_screen.HabitatInfoScreenComponent
import com.alaershov.mars_colony.habitat.list_screen.component.DefaultHabitatListScreenComponent
import com.alaershov.mars_colony.habitat.list_screen.component.HabitatListScreenComponent
import dagger.Binds
import dagger.Module
import org.koin.core.module.Module
import org.koin.dsl.module

@Module
interface HabitatComponentDiModule {
val habitatKoinModule: Module = module {
single<HabitatRepository> { HabitatRepository }

@Binds
fun habitatBuildDialogComponentFactory(
impl: DefaultHabitatBuildDialogComponent.Factory
): HabitatBuildDialogComponent.Factory
factory<HabitatBuildDialogComponent.Factory> {
object : HabitatBuildDialogComponent.Factory {
override fun create(
componentContext: com.arkivanov.decompose.ComponentContext,
onDismiss: () -> Unit,
): HabitatBuildDialogComponent {
return DefaultHabitatBuildDialogComponent(
componentContext = componentContext,
onDismiss = onDismiss,
habitatRepository = get(),
)
}
}
}

@Binds
fun habitatDismantleDialogComponentFactory(
impl: DefaultHabitatDismantleDialogComponent.Factory
): HabitatDismantleDialogComponent.Factory
factory<HabitatDismantleDialogComponent.Factory> {
object : HabitatDismantleDialogComponent.Factory {
override fun create(
componentContext: com.arkivanov.decompose.ComponentContext,
habitatId: String,
onConfirmationNeeded: () -> Unit,
onDismiss: () -> Unit,
): HabitatDismantleDialogComponent {
return DefaultHabitatDismantleDialogComponent(
componentContext = componentContext,
habitatId = habitatId,
onConfirmationNeeded = onConfirmationNeeded,
onDismiss = onDismiss,
habitatRepository = get(),
)
}
}
}

@Binds
fun habitatInfoScreenComponentFactory(
impl: DefaultHabitatInfoScreenComponent.Factory
): HabitatInfoScreenComponent.Factory
factory<HabitatInfoScreenComponent.Factory> {
object : HabitatInfoScreenComponent.Factory {
override fun create(
componentContext: com.arkivanov.decompose.ComponentContext,
habitatId: String,
): HabitatInfoScreenComponent {
return DefaultHabitatInfoScreenComponent(
componentContext = componentContext,
habitatId = habitatId,
)
}
}
}

@Binds
fun habitatListScreenComponentFactory(
impl: DefaultHabitatListScreenComponent.Factory
): HabitatListScreenComponent.Factory
factory<HabitatListScreenComponent.Factory> {
object : HabitatListScreenComponent.Factory {
override fun create(
componentContext: com.arkivanov.decompose.ComponentContext,
onBackClick: () -> Unit,
): HabitatListScreenComponent {
return DefaultHabitatListScreenComponent(
componentContext = componentContext,
onBackClick = onBackClick,
habitatRepository = get(),
habitatBuildDialogComponentFactory = get(),
habitatDismantleDialogComponentFactory = get(),
messageDialogComponentFactory = get(),
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
package com.alaershov.mars_colony.habitat.di

import com.alaershov.mars_colony.habitat.HabitatRepository
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

@Module
class HabitatRepositoryDiModule {

@Singleton
@Provides
fun provideHabitatRepository(): HabitatRepository {
return HabitatRepository
}
}
// Removed Dagger module; Koin module will provide HabitatRepository
Loading