73 lines
2.6 KiB
Kotlin
73 lines
2.6 KiB
Kotlin
|
|
package dev.privacyllc.period.di
|
||
|
|
|
||
|
|
import android.content.Context
|
||
|
|
import androidx.datastore.core.DataStore
|
||
|
|
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
|
||
|
|
import androidx.datastore.preferences.core.Preferences
|
||
|
|
import androidx.datastore.preferences.preferencesDataStoreFile
|
||
|
|
import dagger.Module
|
||
|
|
import dagger.Provides
|
||
|
|
import dagger.hilt.InstallIn
|
||
|
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||
|
|
import dagger.hilt.components.SingletonComponent
|
||
|
|
import dev.privacyllc.period.core.data.CycleData
|
||
|
|
import dev.privacyllc.period.core.data.CycleRepository
|
||
|
|
import dev.privacyllc.period.core.datastore.UserPreferencesRepository
|
||
|
|
import dev.privacyllc.period.domain.prediction.BaselinePredictionEngine
|
||
|
|
import dev.privacyllc.period.domain.prediction.PredictionEngine
|
||
|
|
import java.time.Clock
|
||
|
|
import javax.inject.Singleton
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Where the app learns what a file path is, and the only place it does.
|
||
|
|
*
|
||
|
|
* Note what is absent: no `PeriodDatabase`, no DAO, no Room import anywhere in
|
||
|
|
* this module or anywhere above it. `CycleData.repository` hands back a
|
||
|
|
* repository and keeps the storage to itself — see
|
||
|
|
* docs/architecture/README.md.
|
||
|
|
*/
|
||
|
|
@Module
|
||
|
|
@InstallIn(SingletonComponent::class)
|
||
|
|
object DataModule {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Singleton because Room and DataStore both are: two instances over one
|
||
|
|
* file is a corruption bug that only shows up under concurrency.
|
||
|
|
*/
|
||
|
|
@Provides
|
||
|
|
@Singleton
|
||
|
|
fun cycleRepository(
|
||
|
|
@ApplicationContext context: Context,
|
||
|
|
engine: PredictionEngine,
|
||
|
|
clock: Clock,
|
||
|
|
): CycleRepository = CycleData.repository(context, engine, clock)
|
||
|
|
|
||
|
|
@Provides
|
||
|
|
@Singleton
|
||
|
|
fun preferencesDataStore(@ApplicationContext context: Context): DataStore<Preferences> =
|
||
|
|
PreferenceDataStoreFactory.create {
|
||
|
|
context.preferencesDataStoreFile("user_preferences")
|
||
|
|
}
|
||
|
|
|
||
|
|
@Provides
|
||
|
|
@Singleton
|
||
|
|
fun userPreferencesRepository(store: DataStore<Preferences>) = UserPreferencesRepository(store)
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Batch 02 replaces this binding, and only this binding.
|
||
|
|
*
|
||
|
|
* The rest of the app depends on [PredictionEngine], never on an
|
||
|
|
* implementation — so swapping in the real engine is one line here, and the
|
||
|
|
* §51 acceptance tests can run against both to show the replacement is
|
||
|
|
* better rather than merely different.
|
||
|
|
*/
|
||
|
|
@Provides
|
||
|
|
@Singleton
|
||
|
|
fun predictionEngine(): PredictionEngine = BaselinePredictionEngine()
|
||
|
|
|
||
|
|
/** Injected rather than read from the environment, so §50's date edge cases stay testable. */
|
||
|
|
@Provides
|
||
|
|
@Singleton
|
||
|
|
fun clock(): Clock = Clock.systemDefaultZone()
|
||
|
|
}
|