Stack Overflow на русском Asked on December 7, 2020
Решил добавить clean architecture в свой проект, разбил код на три модуля: domain, data, presentation (он же app). Разбросал весь код по этим трем модулям и у меня возникла проблема с даггером, при попытке собрать приложение пишет что не может получить доступ к WeatherDataApiService (это интерфейс в котором я делаю API запрос с помощью библиотеки retrofit) этот интерфейс я перенес в data модуль. В общем проблема в том что я не пойму как правильно организовать dependency injection чтоб классы имели доступ к друг-другу. Получается во время сборки Даггера доступ к data модулю закрыт. Проблема в том что нужно правильно распределить зависимости между модулями.На данный момент у меня зависимости между модулями выстроены таким образом – presentation(app) зависит от domain модуля, а domain модуль зависит от data модуля
Это интерфейс WeatherDataApiService
interface WeatherDataApiService {
@GET("/v2.0/forecast/daily")
fun getWeatherData(
@Query("city") city: String,
@Query("days") days: Int,
@Query("units") degreeType: String
):Single<WeatherDataApiModel>
companion object {
operator fun invoke(): WeatherDataApiService {
val key = "40a7956799be42f49bc8b6ac4bb8e432"
val requestInterceptor = Interceptor{chain->
val url = chain.request()
.url() // HttpUrl
.newBuilder() // HttpUrl.Builder
.addQueryParameter("key", key) // HttpUrl.Builder
.build()
val request = chain.request()
.newBuilder() // Request.Builder
.url(url) // Request.Builder
.build() // Request
return@Interceptor chain.proceed(request) // Response
}
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(requestInterceptor) // OkHttpClient.Builder()
.build()
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://api.weatherbit.io")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.build()
.create(WeatherDataApiService::class.java)
}
}
}
Это репозиторий который находится в domain модуле
class WeatherDataRepositoryImpl @Inject constructor(
private val weatherDataApiService : WeatherDataApiService,
private val mapper : WeatherDataMapper
) : WeatherDataRepository {
override fun getWeatherData(
city: String,
days: Int,
degreeType: String
): Single<WeatherData> =
weatherDataApiService.getWeatherData(city, days, degreeType)
.map { mapper.mapWeather(it) }
}
Это код use case где я задействую репозиторий
class FetchWeatherDataUseCase @Inject constructor(private val weatherDataRepository: WeatherDataRepository) {
fun fetchWeatherData(city: String,days: Int,degreeType: String): Single<WeatherData> {
return weatherDataRepository.getWeatherData(city,days,degreeType)
}
}
Это код Даггер модуля который находится в domain
@Module
class WeatherDataRepositoryModule {
@Provides
@Singleton
fun providerWeatherDataRepository(
mapper: WeatherDataMapper,
weatherDataApiService: WeatherDataApiService
): WeatherDataRepository =
WeatherDataRepositoryImpl(
weatherDataApiService,
mapper
)
@Provides
@Singleton
fun providerApiService() = WeatherDataApiService()
@Provides
fun providerMapper() = WeatherDataMapper()
}
Это код Даггер модуля который находится в presentation(app)
@Module
class WeatherDataModule {
@Provides
@Singleton
fun provideFetchWeatherDataUseCase(weatherDataRepository: WeatherDataRepository) =
FetchWeatherDataUseCase(weatherDataRepository)
}
Это код Даггер компонента который находится в presentation(app)
@Singleton
@Component(modules = [WeatherDataModule::class, WeatherDataRepositoryModule::class])
interface WeatherDataComponent {
fun injectWeatherDataFragment(weatherDataFragment: WeatherDataFragment)
}
Здесь я создаю даггер, код находится в presentation(app)
class App : Application() {
lateinit var weatherDataComponent: WeatherDataComponent
override fun onCreate() {
super.onCreate()
weatherDataComponent = DaggerWeatherDataComponent.create()
}
}
Текст ошибки – cannot access WeatherDataApiService
Проблема решена. Проблема заключалась в зависимостях между модулями которые нужно было установить в build.gradle, нужно было правильно расставить зависимости. Как правило presentation(app) зависит от data и от domain, data зависит от domain, а domain не зависит ни от кого.
build.gradle(Module.app)
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
...
implementation project(path: ':domain')
implementation project(path: ':data')
}
build.gradle(Module.data)
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
...
implementation project(path: ':domain')
}
Answered by Artem on December 7, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP