I have an interface PaymentProvider:
interface PaymentProvider {
fun pay(amount: Double): Boolean
}
Here is different implementations:
class PayPalPayment @AssistedInject constructor(
private val payPalRepo: PayPalRepository,
@Assisted private val paymentData: PaymentData
): PaymentProvider {
@AssistedFactory
interface Factory : PaymentProviderFactory
override fun pay(amount: Double): Boolean {
// some code
}
}
class CreditCardPayment(
private val creditCardPaymentRepo: CreditCardPaymentRepository
): PaymentProvider {
override fun pay(amount: Double): Boolean {
// some code
}
}
Also I have PaymentManager class who should receive PaymentProvider.
class PaymentManager(
private val paymentProvider:PaymentProvider
) {
// some logic
}
I want this class not to know which specific implementation of the PaymentProvider interface it works with. For this I'm provide with dagger implementation using multibindings. Here is my code:
@Binds
@[IntoMap PaymentProviderKey(Keys.PAYPAL)]
fun bindPayPalPayment (factory: PayPalPayment.Factory): PaymentProviderFactory
@Binds
@[IntoMap PaymentProviderKey(Keys.CREDIT_CARD)]
fun bindCreditCardPayment (factory: CreditCardPayment.Factory): PaymentProviderFactory
interface PaymentProviderFactory{
fun create(key: PaymentProviderKey, paymentData: PaymentData): PaymentProvider
}
Now I have a map of factories, but I don't understand how to provide specific implementation of interface. I tried to provide PaymentProviderFactory:
@Provides
fun providePaymentManager(
factory: PaymentProviderFactory
): PaymentManager = PaymentManager (
factory
)
and i get this kind of error:
Invalid return type: PaymentProvider. An assisted factory's abstract method must return a type with an @AssistedInject-annotated constructor.
Please, help me. I have a problem when using @AssistedInject
, without it I provide map of PaymentProvider and then I provide factory to create concrete implementation:
@Provides
fun providePaymentProviderFactory(
paymentProviders: Map<PaymentProviderKey, @JvmSuppressWildcards Provider<PaymentProvider>>
): PaymentProviderFactory=
object : PaymentProviderFactory{
override fun create(key: PaymentProviderKey): PaymentProvider? {
val paymentProvider = paymentProviders[key]
return paymentProvider?.get()
}
}
In this case everything works, however I need to use @AssistedInject because I need to pass the data that I receive at runtime.