Что мне нужно, это:
Иметь одноэлементный объект DataStore
DataStore выполнит http-запрос, поэтому в нем необходимо установить apis Retrofit, например (UserApi - это интерфейс для модификации)
Фрагменты и действия будут содержать DataStore, но они также могут иметь некоторые другие Api
пример концепции, которая мне нужна:
class DataStore {
@Inject lateinit var userApi: UserApi
}
class Fragment1 : Fragment() {
@Inject lateinit var dataStore: DataStore
@Inject lateinit var testApi: TestApi
}
Мне удалось внедрить API в ViewModel, который был создан с помощью фабрики, но мне нужно одно хранилище данных, и я знаю, что зависимость от приложения является частью проблемы. Также, похоже, проблема с введением userApi в FormFragment.
Вот что у меня есть
MainApplication
class MainApplication : Application() {
lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
StateSaver.setEnabledForAllActivitiesAndSupportFragments(this, true)
appComponent = DaggerAppComponent.builder()
.userModule(UserModule(this))
.retrofitModule(RetrofitModule())
.build()
}
AppComponent
@Singleton
@Component(modules = [RetrofitModule::class, UserModule::class])
interface AppComponent {
fun inject(mainActivity: MainActivity)
fun inject(formFragment: formFragment)
fun inject(dataStore: DataStore)
fun userApi(): UserApi
fun testApi(): TestApi
}
UserModule
@Module
class UserModule(var mainApplication: MainApplication) {
@Singleton
@Provides
fun provideDataStore() : DataStore = DataStore(mainApplication)
}
RetrofitModule
@Module
class RetrofitModule {
private val TAG: String = RetrofitModule::class.java.simpleName
@Singleton
@Provides
fun provideRetrofit() : Retrofit {
Log.e(TAG, "Creating retrofit ...")
val httpClient = OkHttpClient.Builder()
.addInterceptor {
val request = it.request()
if (BuildConfig.DEBUG) {
Log.d(TAG, "${request.method()}: ${request.url()}")
}
it.proceed(request)
}
.build()
return Retrofit.Builder()
.client(httpClient)
.baseUrl("http://192.168.0.13:3000")
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(JacksonConverterFactory.create(jacksonObjectMapper()))
.build()
}
@Provides
fun provideUserApi(retrofit: Retrofit) : UserApi {
return retrofit.create(UserApi::class.java)
}
@Provides
fun provideTestApi(retrofit: Retrofit) : TestApi {
return retrofit.create(TestApi::class.java)
}
}
DataStore
class DataStore @Inject constructor(application: MainApplication) {
init {
application.appComponent.inject(this)
}
@Inject
lateinit var userApi: userApi
...
FormFragment
class FormFragment : Fragment() {
@Inject
lateinit var dataStore: DataStore
@Inject
lateinit var testApi: TestApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val application = requireActivity().application as MainApplication
application.appComponent.inject(this)
}
Я получаю
MainApplication cannot be provided without an @Inject constructor or an @Provides-annotated method
в хранилище данных
Если я удаляю var mainApplication
из хранилища данных, я получаю сообщение об ошибке, что TestApi не может быть предоставлен без конструктора @Inject .. в FormFragment