Я разрабатываю приложение для Android с Kotlin, в котором мне нужно получить текущее местоположение мобильного устройства. Я уже нашел способ сделать это в различных примерах, но я не знаю, как интегрировать эту логику в соответствии с чистой архитектурой с MVVM.
В моей архитектуре есть следующие уровни: презентация, прецедент, данные, домен и фреймворк. У меня есть уровень представления, организованный с помощью шаблона MVVM. Также я использую Koin для внедрения зависимостей.
Я получаю все данные, которые нужны моему приложению, из источников данных, находящихся на уровне Framework. Например, данные, полученные удаленно или из базы данных, или данные, предоставленные устройством (местом).
Вот пример файлов, участвующих в получении местоположения из ViewModel:
ConfigurationViewModel (уровень представления):
class ConfigurationViewModel(private val useCase: GetLocationUseCase) : ViewModel() {
fun onSearchLocationButtonClicked() = liveData<Resource<Location>>(Dispatchers.IO) {
emit(Resource.loading())
try {
emit(Resource.success(data = useCase.invoke(UseCase.None())))
} catch (exception: Exception) {
emit(Resource.error(message = exception.message))
}
}
GetLocationUseCase (уровень использования):
class GetLocationUseCase(private val locationRepository: LocationRepository) :
UseCase<Location, UseCase.None>() {
override suspend fun invoke(params: None): Location = locationRepository.getLocation()
}
LocationRepositoryImpl (уровень данных):
class LocationRepositoryImpl(private val locationDeviceDataSource: LocationDeviceDataSource) :
LocationRepository {
override suspend fun getLocation(): Location = locationDeviceDataSource.getLocation()
}
LocationDeviceDataSourceImpl (уровень инфраструктуры):
class LocationDeviceDataSourceImpl(private val context: Context) : LocationDeviceDataSource {
override suspend fun getLocation(): Location =
LocationServices.getFusedLocationProviderClient(context).lastLocation.await()
}
Как видите, в LocationDeviceDataSourceImpl мне нужен контекст, чтобы получить последнее местоположение. Я не знаю, как лучше всего предоставить контекст для источника данных. Я видел несколько примеров, но хочу понять, как лучше всего это сделать.
Я видел следующие варианты:
Используйте AndroidViewModel, чтобы предоставить контекст приложения для UseCase, чтобы передать его в репозиторий, чтобы, наконец, предоставить его источнику данных. Но я не уверен, что это подходящий способ, безопасен ли он и сохраняет ли он архитектурный смысл. На основе ответа Алекса
Другой вариант, который я видел, - это вставить androidContext через Koin в DataSource, что является еще одним способом предоставить контекст приложения. Таким образом, контексту не обязательно проходить через ViewModel, UseCase или Repository. На основе ответа Маслика
Как лучше всего интегрировать эту логику в соответствии с моей архитектурой и почему? Или это проблема в моей архитектуре?
Большое спасибо за уделенное время.