Мне трудно понять, как настроить иерархию компонентов Dagger в соответствии с моим видением.Любая помощь будет принята с благодарностью, и, пожалуйста, не стесняйтесь критиковать это видение, если вы обнаружите в ней какие-либо дыры.
Давайте перейдем к делу.
Я пытаюсь пересмотреть часть своего заявлениясвязанные с регистрацией пользователей.Поскольку регистрация является автономным доменом, я предполагаю, что это хороший кандидат для отдельного компонента кинжала (RegistrationSubcomponent).В этом домене регистрации я покажу активность (RegistrationActivity), а поверх нее несколько фрагментов (RegistrationFragment1, RegistrationFragment2, ...).У меня уже есть компонент приложения (AppComponent) с жизненным объемом приложения, который должен быть родительским для RegistrationSubcomponent.AppComponent используется для внедрения зависимостей в другие активности, кроме RegistrationActivity, но также и в общую активность (CommonActivity), которая является родительской для каждой активности в моем приложении, включая RegistrationActivity.Чтобы добавить зависимости в RegistrationActivity, я хочу использовать RegistrationSubcomponent.
Элемент RegistrationSubponent должен быть создан незадолго до отображения RegistrationActivity и должен существовать до тех пор, пока не будет возвращено RegistrationActivity.Я не хочу связывать жизненный цикл RegistrationSubcomponent с жизненным циклом RegistrationActivity.Mayby, в этом случае это может иметь смысл, но в будущем я, вероятно, хотел бы создать компоненты для других доменов приложений, которые могут не соответствовать жизненному циклу действий, которые они охватывают.
В общем, проблема заключается во внедрении указанных зависимостейв RegistrationComponent в RegistrationActivity, а также в RegistrationFragments.
Проблема заключается в том, что приложение вызывает сбой при переходе к RegistrationActivity со следующей ошибкой: невозможно запустить действие ComponentInfo {pl.kermit.diproblem / pl.kermit.diproblem.activities.RegistrationActivity}: java.lang.IllegalArgumentException: нет фабрики инжекторов, привязанной к классу
Минимальный проект, представляющий проблему, можно найти по адресу https://github.com/mariola3000/DIProblemStack01
Ниже я поместил наиболее важные части кода
// КОМПОНЕНТ APP
@Singleton
@Component(modules = [AndroidInjectionModule::class, AppModule::class, AppAndroidBindingModule::class,
AndroidSupportInjectionModule::class])
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
fun inject(application: Application)
}
@Module(subcomponents = [RegistrationComponent::class])
class AppModule {
@Provides
fun provideGlobalDependency(): GlobalDependency {
return GlobalDependency("GlobalDependency")
}
@Provides
fun provideGlobal2Dependency(): Global2Dependency {
return Global2Dependency("Global2Dependency")
}
}
@Module
abstract class AppAndroidBindingModule {
@PerActivity
@ContributesAndroidInjector()
abstract fun bindMainActivity(): MainActivity
}
// КОМПОНЕНТ РЕГИСТРАЦИИ
@PerRegistration
@Subcomponent(modules = [RegistrationModule::class, RegistrationAndroidBindingModule::class])
interface RegistrationComponent {
@Subcomponent.Builder
interface Builder {
fun requestModule(module: RegistrationModule): Builder
fun build(): RegistrationComponent
}
}
@Module
class RegistrationModule {
@PerRegistration
@Provides
fun provideRegistrationDependency(): RegistrationDependency {
return RegistrationDependency("RegistrationDependency")
}
@PerRegistration
@Provides
fun provideRegistrationFragmentDependency(): RegistrationFragmentDependency {
return RegistrationFragmentDependency("RegistrationFragmentDependency")
}
}
@Module
abstract class RegistrationAndroidBindingModule {
@PerActivity
@ContributesAndroidInjector
abstract fun bindRegistrationActivity(): RegistrationActivity
@PerFragment
@ContributesAndroidInjector
abstract fun bindRegistrationFragment(): RegistrationFragment
}
// ДЕЯТЕЛЬНОСТЬ
abstract class CommonActivity : DaggerAppCompatActivity(){
@Inject
lateinit var globalDependency: GlobalDependency
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
Toast.makeText(this, "global message: " + globalDependency.message, Toast.LENGTH_LONG).show()
}
}
class MainActivity : CommonActivity() {
@set:Inject
lateinit var global2Dependency: Global2Dependency
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val text: TextView = findViewById(R.id.main_text)
text.text = global2Dependency.message
val button: Button = findViewById(R.id.main_button)
button.setOnClickListener {
startActivity(Intent(this, RegistrationActivity::class.java))
}
}
}
class RegistrationActivity : CommonActivity() {
@Inject
lateinit var registrationDependency: RegistrationDependency
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_registration)
val registrationMessage = findViewById<TextView>(R.id.registration_text)
registrationMessage.text = registrationDependency.message
val transaction = this.supportFragmentManager.beginTransaction()
val fragment = RegistrationFragment()
transaction.replace(R.id.registration_fragment_container, fragment)
transaction.addToBackStack(fragment.javaClass.simpleName)
transaction.commit()
}
}