Мультимодульный проект - Dagger - PullRequest
1 голос
/ 03 октября 2019

В моем проекте Android у меня есть:

  • ядро ​​ библиотечный модуль
  • ui_add_credit_card библиотечный модуль
  • app в качестве модуля приложения

В core определено AppComponent:

@Singleton
@Component(
        modules = {
                AppModule.class,
                NetworkModule.class,
                ViewModelFactoryModule.class,
        }
)
public interface AppComponent {

и специальный модуль для ViewModulesмодуль связывания ViewModelFactoryModule:

@Module
abstract class ViewModelFactoryModule {

    @Binds
    abstract fun bindViewModelFactory(viewModelFactory: DaggerViewModelFactory): ViewModelProvider.Factory

    @Binds
    @IntoMap
    @ViewModelKey(SplashViewModel::class)
    abstract fun bindSplashViewModel(viewModel: SplashViewModel): ViewModel
...

DaggerViewModelFactory - это специальная ViewModelProvider.Factory, которая позаботится о именовании ключей ViewModel, поэтому для инъекций операций / фрагментов не нужно заботиться об этом:

class DaggerViewModelFactory @Inject constructor(
        private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        val creator = creators[modelClass] ?: creators.entries.firstOrNull {
            modelClass.isAssignableFrom(it.key)
        }?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
        try {
            @Suppress("UNCHECKED_CAST")
            return creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }    }
}

Это все отлично работает:)

Проблема в том, что я хочу создать дополнительные AddCreditCardComponent и AddCreditCardViewModelModule для отдельного модуля проекта ui_add_credit_card .

@Component(
        dependencies = [AppComponent::class],
        modules = [
            AddCreditCardViewModelModule::class
        ])
interface AddCreditCardComponent {

    fun inject(creditCardRegisterActivity: CreditCardRegisterActivity)
}
@Module
abstract class AddCreditCardViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(CreditCardViewModel::class)
    abstract fun bindCreditCardRegistrationViewModel(
            viewModel: CreditCardRegistrationViewModel
    ): ViewModel

}

Я получаю следующую ошибку:

AddCreditCardComponent.java: 8: ошибка: [Dagger / MissingBinding] androidx.lifecycle.ViewModelProvider.Factory не может быть предоставленабез @ Предоставляет аннотированный метод.

Любая помощь? Я предположил, что ViewModelProvider.Factory должен быть предоставлен моим ViewModelFactoryModule, но этого не происходит: (

1 Ответ

0 голосов
/ 04 октября 2019

Мне удалось решить мою проблему, создав модуль AddCreditCardViewModelModule другим способом (@Provide вместо @Binds), и мне пришлось создать специализированный ViewModel.Factory, который будет выполнять добавленную реализацию ViewModel.

@Module
object AddCreditCardViewModelModule {

    @JvmStatic @Provides
    fun provideAddCreditCardViewModelFactory(
            adyenApi: AdyenApi,
            paymentController: PaymentController
    ) = AddCreditCardViewModelFactory(adyenApi, paymentController)

}

также (от thx до David Medenjak ) было важно убедиться, что зависимости (например, AdyenApi) от AppComponent выставлены как «добытчик». В противном случае AddCreditCardComponent не будет иметь к нему доступа.

Приветствия!

...