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
13 changes: 8 additions & 5 deletions app/src/main/java/com/otus/dihomework/ProductsApplication.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.otus.dihomework

import android.app.Application
import com.otus.dihomework.di.AppComponent
import com.otus.dihomework.di.DaggerAppComponent
import com.otus.dihomework.di.DependenciesProvider

class ProductsApplication : Application() {
override fun onCreate() {
super.onCreate()
ServiceLocator.init(this)
}
class ProductsApplication : Application(), DependenciesProvider {

val component: AppComponent = DaggerAppComponent.factory().create(this)

override fun getDependencies() = component
}
106 changes: 0 additions & 106 deletions app/src/main/java/com/otus/dihomework/ServiceLocator.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import androidx.datastore.preferences.preferencesDataStore
import com.otus.dihomework.common.domain_impl.FavoritesRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "favorites")

class FavoritesRepositoryImpl(
class FavoritesRepositoryImpl @Inject constructor(
private val context: Context
) : FavoritesRepository {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.otus.dihomework.common.data

import com.otus.dihomework.common.domain_api.Product
import javax.inject.Inject

class ProductDomainMapper() {
class ProductDomainMapper @Inject constructor() {

fun fromDto(dto: ProductDto): Product {
return Product(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.otus.dihomework.common.data

import com.otus.dihomework.ServiceLocator
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import javax.inject.Inject

class ProductRemoteDataSource() {
private val apiService = ServiceLocator.getProductApiService()
class ProductRemoteDataSource @Inject constructor(
private val apiService: ProductApiService
) {

fun consumeProducts(): Flow<List<ProductDto>> = flow {
emit(apiService.getProducts())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.otus.dihomework.common.data

import com.otus.dihomework.ServiceLocator
import com.otus.dihomework.common.domain_impl.ProductRepository
import com.otus.dihomework.common.domain_api.Product
import com.otus.dihomework.common.domain_impl.ProductRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class ProductRepositoryImpl() : ProductRepository {

private val remoteDataSource = ServiceLocator.getProductRemoteDataSource()
private val mapper = ServiceLocator.getProductDomainMapper()
class ProductRepositoryImpl @Inject constructor(
private val remoteDataSource: ProductRemoteDataSource,
private val mapper: ProductDomainMapper
) : ProductRepository {

override fun consumeProducts(): Flow<List<Product>> {
return remoteDataSource.consumeProducts()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.otus.dihomework.common.domain_impl

import com.otus.dihomework.ServiceLocator
import com.otus.dihomework.common.domain_api.ConsumeFavoritesUseCase
import com.otus.dihomework.common.domain_api.ProductWithFavorite
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import javax.inject.Inject

class ConsumeFavoritesUseCaseImpl() : ConsumeFavoritesUseCase {

private val productRepository = ServiceLocator.getProductRepository()
private val favoritesRepository = ServiceLocator.getFavoritesRepository()
class ConsumeFavoritesUseCaseImpl @Inject constructor(
private val productRepository: ProductRepository,
private val favoritesRepository: FavoritesRepository
) : ConsumeFavoritesUseCase {

override fun invoke(): Flow<List<ProductWithFavorite>> {
return combine(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.otus.dihomework.common.domain_impl

import com.otus.dihomework.ServiceLocator
import com.otus.dihomework.common.domain_api.ConsumeProductsUseCase
import com.otus.dihomework.common.domain_api.ProductWithFavorite
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class ConsumeProductsUseCaseImpl() : ConsumeProductsUseCase {

private val productRepository = ServiceLocator.getProductRepository()
private val favoritesRepository = ServiceLocator.getFavoritesRepository()
class ConsumeProductsUseCaseImpl
@Inject constructor(
private val productRepository: ProductRepository,
private val favoritesRepository: FavoritesRepository
) : ConsumeProductsUseCase {

override fun invoke(): Flow<List<ProductWithFavorite>> {
return combine(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.otus.dihomework.common.domain_impl

import com.otus.dihomework.ServiceLocator
import com.otus.dihomework.common.domain_api.ToggleFavoriteUseCase
import javax.inject.Inject

class ToggleFavoriteUseCaseImpl() : ToggleFavoriteUseCase {

private val favoritesRepository = ServiceLocator.getFavoritesRepository()
class ToggleFavoriteUseCaseImpl @Inject constructor(
private val favoritesRepository: FavoritesRepository
) : ToggleFavoriteUseCase {

override suspend fun invoke(productId: String, isFavorite: Boolean) {
if (isFavorite) {
Expand Down
28 changes: 28 additions & 0 deletions app/src/main/java/com/otus/dihomework/di/AppComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.otus.dihomework.di

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import javax.inject.Singleton

@Singleton
@Component(
modules = [
NetModule::class,
RepositoryModule::class,
DomainModule::class,
UtilsModule::class,
SubcomponentsModule::class,
]
)
interface AppComponent : ProductDependencies {

fun favoritesComponent(): FavoritesComponent.Factory

@Component.Factory
interface Factory {
fun create(
@BindsInstance context: Context
): AppComponent
}
}
13 changes: 13 additions & 0 deletions app/src/main/java/com/otus/dihomework/di/Dependencies.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.otus.dihomework.di

import android.content.Context

interface Dependencies

interface DependenciesProvider {
fun getDependencies(): Dependencies
}

inline fun <reified T : Dependencies> Context.findDependencies(): T {
return (applicationContext as DependenciesProvider).getDependencies() as T
}
23 changes: 23 additions & 0 deletions app/src/main/java/com/otus/dihomework/di/DomainModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.otus.dihomework.di

import com.otus.dihomework.common.domain_api.ConsumeFavoritesUseCase
import com.otus.dihomework.common.domain_api.ConsumeProductsUseCase
import com.otus.dihomework.common.domain_api.ToggleFavoriteUseCase
import com.otus.dihomework.common.domain_impl.ConsumeFavoritesUseCaseImpl
import com.otus.dihomework.common.domain_impl.ConsumeProductsUseCaseImpl
import com.otus.dihomework.common.domain_impl.ToggleFavoriteUseCaseImpl
import dagger.Binds
import dagger.Module

@Module
abstract class DomainModule {

@Binds
abstract fun getConsumeFavoritesUseCase(impl: ConsumeFavoritesUseCaseImpl): ConsumeFavoritesUseCase

@Binds
abstract fun getConsumeProductsUseCase(impl: ConsumeProductsUseCaseImpl): ConsumeProductsUseCase

@Binds
abstract fun getToggleFavoriteUseCase(impl: ToggleFavoriteUseCaseImpl): ToggleFavoriteUseCase
}
17 changes: 17 additions & 0 deletions app/src/main/java/com/otus/dihomework/di/FavoritesComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.otus.dihomework.di

import com.otus.dihomework.common.di.FeatureScope
import com.otus.dihomework.features.favorites.FavoritesViewModelFactory
import dagger.Subcomponent

@FeatureScope
@Subcomponent
interface FavoritesComponent {

fun viewModelFactory(): FavoritesViewModelFactory

@Subcomponent.Factory
interface Factory {
fun create(): FavoritesComponent
}
}
45 changes: 45 additions & 0 deletions app/src/main/java/com/otus/dihomework/di/NetModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.otus.dihomework.di

import com.google.gson.GsonBuilder
import com.otus.dihomework.common.data.ProductApiService
import dagger.Module
import dagger.Provides
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
import javax.inject.Singleton

@Module
class NetModule {

@Singleton
@Provides
fun retrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder().baseUrl("https://otus-android.github.io/").client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().create())).build()
}

@Singleton
@Provides
fun okHttpClient(httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS)
.build()
}

@Provides
fun httpLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
}

@Singleton
@Provides
fun productApiService(retrofit: Retrofit): ProductApiService {
return retrofit.create(ProductApiService::class.java)
}
}
14 changes: 14 additions & 0 deletions app/src/main/java/com/otus/dihomework/di/ProductDependencies.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.otus.dihomework.di

import com.otus.dihomework.common.domain_api.ConsumeProductsUseCase
import com.otus.dihomework.common.domain_api.ToggleFavoriteUseCase
import com.otus.dihomework.common.util.PriceFormatter
import com.otus.dihomework.features.products.ProductsStateFactory

interface ProductDependencies: Dependencies {

fun consumeProductsUseCase(): ConsumeProductsUseCase
fun toggleFavoriteUseCase(): ToggleFavoriteUseCase
fun priceFormatter(): PriceFormatter
fun productsStateFactory(): ProductsStateFactory
}
Loading