Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass injector directly into FormViewModel #5738

Merged
merged 2 commits into from
Oct 25, 2022
Merged

Conversation

brnunes-stripe
Copy link
Contributor

Summary

FormViewModel's lifecycle is always strictly contained within the PaymentSheet lifecycle. Therefore, it doesn't need to be able to recreate the whole dependency graph.
FormViewModel.Factory now receives the injector as a parameter, which guarantees that it will reuse all already created dependencies. This allows us to delete FormViewModelComponent, which was used by FormViewModel during fallback injection.
BaseSheetViewModel is now responsible for injecting into the ViewModels with smaller lifecycle, similar to how LinkActivityViewModel holds an injector that is passed to the screen-specific ViewModels. PaymentOptionsViewModel.Factory and PaymentSheetViewModel.Factory create the NonFallbackInjector and set it into BaseSheetViewModel.

Motivation

Fix #5737

Testing

  • Added tests
  • Modified tests
  • Manually verified

Comment on lines 335 to +382
val application = applicationSupplier()
val starterArgs = starterArgsSupplier()
injectWithFallback(
starterArgsSupplier().injectorKey,
FallbackInitializeParam(application, starterArgs.productUsage)
)
return subComponentBuilderProvider.get()
val logger = Logger.getInstance(BuildConfig.DEBUG)

WeakMapInjectorRegistry.retrieve(starterArgs.injectorKey)?.let {
it as? NonFallbackInjector
}?.let {
logger.info(
"Injector available, " +
"injecting dependencies into ${this::class.java.canonicalName}"
)
injector = it
it.inject(this)
} ?: run {
logger.info(
"Injector unavailable, " +
"initializing dependencies of ${this::class.java.canonicalName}"
)
fallbackInitialize(FallbackInitializeParam(application, starterArgs.productUsage))
}

val subcomponent = subComponentBuilderProvider.get()
.application(application)
.args(starterArgs)
.savedStateHandle(savedStateHandle)
.build().viewModel as T
.build()
val viewModel = subcomponent.viewModel
viewModel.injector = injector
return viewModel as T
}

override fun fallbackInitialize(arg: FallbackInitializeParam) {
val component = DaggerPaymentOptionsViewModelFactoryComponent.builder()
.context(arg.application)
.productUsage(arg.productUsage)
.build()

injector = object : NonFallbackInjector {
override fun inject(injectable: Injectable<*>) {
when (injectable) {
is FormViewModel.Factory -> component.inject(injectable)
else -> {
throw IllegalArgumentException("invalid Injectable $injectable requested in $this")
}
}
}
}
component.inject(this)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is now replicated in PaymentOptionsViewModel, PaymentSheetViewModel and LinkActivityViewModel. I'll refactor to make it generic and part of the stripe-core module in the next PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -150,7 +150,7 @@ complexity:
thresholdInObjects: 11
thresholdInEnums: 11
ignoreDeprecated: false
ignorePrivate: false
ignorePrivate: true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What’s the reason for the changes in this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Detekt was failing for one of the files for having more than 11 methods, I think ignoring private methods is a good change to make it a little more flexible.

@brnunes-stripe brnunes-stripe merged commit e84d629 into master Oct 25, 2022
@brnunes-stripe brnunes-stripe deleted the brnunes/fix branch October 25, 2022 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Crash when trying to present payment sheet with setup intent
3 participants