У меня есть два модуля проекта (под этим я подразумеваю два android модуля с их собственным gradle, manifest и т. Д. c. Не модуль Dagger). Я называю их MyAppCore и MyApp. MyAppCore имеет логику c вокруг доступа к базе данных и доступа к сети. MyApp имеет весь пользовательский интерфейс (действия, представления, модельные представления и т. Д. c).
Я использую кинжал 2 для внедрения зависимостей различных компонентов в мой проект, однако у меня возникают проблемы, чтобы связать оба модули вместе.
MyApp и MyAppCore имеют свой собственный AppComponent, где MyApp предоставляет фабрики ViewModel, а MyAppCore - фабрики для доступа к базе данных и сети (примеры ниже).
Я не уверен, как связать и AppComponent (или Приложения) так, чтобы доступ к базе данных и сети мог быть обеспечен в MyApp. Вот что у меня есть:
Модуль MyAppCore
CoreApp
open class CoreApp : Application() {
val appComponent: AppComponent by lazy {
initializeComponent()
}
open fun initializeComponent(): AppComponent {
return DaggerAppComponent.builder()
.build()
}
}
AppComponent
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
}
AppModule
@Module
class AppModule {
@Singleton
@Provides
fun provideDb(app: Application) = MyDb.getInstance(app)
@Singleton
@Provides
fun provideCommentDao(db: MyDb) = db.commentDao()
}
CommentRep (для доступа к CommentDao)
@Singleton
class CommentRep @Inject constructor(private val dao: CommentDao) {
fun saveComment(comment: Comment){
dao.insert(comment)
}
}
MyAppCore также имеет реализацию базы данных Room под названием MyDb
и интерфейс CommentDao
(я не думаю, что мне нужно добавлять этот код в этом вопросе).
модуль MyApp
MyApp
open class MyApp : Application(), DaggerComponentProvider {
override val appComponent: AppComponent by lazy {
initializeComponent()
}
open fun initializeComponent(): AppComponent {
return DaggerAppComponent.builder()
.applicationContext(applicationContext)
.build()
}
}
DaggerComponentProvider
interface DaggerComponentProvider {
val appComponent: AppComponent
}
val Activity.injector get() = (application as DaggerComponentProvider).appComponent
AppComponent
@Singleton
@Component
interface AppComponent{
@Component.Builder
interface Builder {
@BindsInstance
fun applicationContext(applicationContext: Context): Builder
fun build(): AppComponent
}
fun commentsViewModelFactory(): ViewModelFactory<CommentsViewModel>
}
ViewModelFactory
class ViewModelFactory<VM : ViewModel> @Inject constructor(
private val viewModel: Provider<VM>
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>) = viewModel.get() as T
}
CommentsViewModel
class CommentsViewModel @Inject constructor(private val repository: CommentRep) : ViewModel() {
fun saveComment(comment: Comment){
repository.saveComment(comment)
}
}
А затем мои действия, которые внедряют ВМ, но я не думаю, что они необходимы для включения их кода в это вопрос.
Конечно, если я скомпилирую свой проект как этот, график из MyAppCore не будет сгенерирован, и, следовательно, я получаю ошибку, которую мне нужно предоставить CommentDao
, потому что это требуется для CommentRep
, который используется на CommentsViewModel
. Я предполагаю, что класс приложения MyAppCore переопределяется классом приложения MyApp, и, следовательно, AppComponent
MyAppCore никогда не создается и, следовательно, никогда не добавлял все инъекции ядра в мой график. Как мне решить эту проблему? Заранее спасибо!