BillingDataSource
又名
BillingClientWrapper
需要一个单例
BillingClient
对象,但是如果没有
BillingClient
中的侦听器,就无法完成创建
BillingDataSource
对象:
class BillingDataSource(private val client: BillingClient) {
private val _purchases = MutableStateFlow<List<Purchase>?>(mutableListOf())
val purchases = _purchases.asStateFlow()
val PURCHASES_UPDATED_LISTENER = PurchasesUpdatedListener { result, purchases ->
_purchases.value = purchases
}
}
以及依赖注入:
@Provides
@Singleton
fun provideBillingClient(
@ApplicationContext context: Context,
wrapper: BillingDataSource
) : BillingClient {
return BillingClient.newBuilder(context)
.setListener(wrapper.PURCHASES_UPDATED_LISTENER)
.enablePendingPurchases()
.build()
}
@Provides
@Singleton
fun provideBillingDataSource(
client: BillingClient
) : BillingDataSource = BillingDataSource(client)
构建 .setListener
时的
BillingClient
要求确实令人头疼。当然,我可以通过将侦听器放在
BillingDataSource
之外来打破循环依赖关系,但这样我就会失去对
_purchases
内部成员(如
BillingDataSource
)的访问权限,这并不理想。我该如何解决这个问题?
BillingClient
作为
BillingDataSource
的 internal依赖项是有意义的。然后
BillingDataSource
成为应用程序其余部分与其交互的唯一方式:
class BillingDataSource(@ApplicationContext context: Context) {
private val _purchases = MutableStateFlow<List<Purchase>?>(mutableListOf())
val purchases = _purchases.asStateFlow()
private val client = BillingClient.newBuilder(context)
.setListener { result, purchases ->
_purchases.value = purchases
}
.enablePendingPurchases()
.build()
// expose other interactions with client here
}
通常,在构造函数中创建依赖项不是一个好主意,但在这种情况下,它不会破坏可测试性,因为所有模拟或存根都可以在 BillingDataSource
级别上完成。