[英]Scala dependency injection when using case class/companion object pattern
[英]Scala - Dependency injection in companion objects
我来自 Java 背景并且不熟悉函数范式,所以请原谅并纠正我,我闻起来像 OOP。
我有一个特征名称 PaymentHandler
trait PaymentHandler {
def handleInit(paymentInfo: PaymentInfo, paymentConfig: PaymentConfig): Either[Future[WSResponse], Exception]
def handleComplete(paymentinfo: PaymentInfo, paymentConfig: PaymentConfig, clientToken: String): Future[Map[String, String]]
}
和
@Singleton
class PayPal extends PaymentHandler{....}
@Singleton
class BrainTree extends PaymentHandler{....}
到这里一切正常。 但是当我想要基于 Payment 方法拥有多个 PaymentGateways 时,问题就来了。 最初我写了一个 PaymentHandlerFactory 像
class PaymentHandlerFactory @Inject()(
paypal:PayPal,
braintree:BrainTree) {
def get(name:String): PaymentHandler = {
name match {
case "paypal" => paypal
case "bt" => braintree
case _ => null
}
}
}
然后使用这个 PaymentHandlerFactory 来获取 guice 注入的 PayPal 对象。 但不知何故,我觉得这不是正确的做法,于是我找到了伴生对象。 所以这是我当时写的代码
object PaymentHandler {
@Inject
val paypal:PayPal = null
def apply(name:String): PaymentHandler = {
name match {
case "paypal" => paypal
case _ => null
}
}
}
当然这失败了,因为它不能注入 PayPal 对象。 现在我脑子里有两个问题。
不能注入伴生对象的原因是因为它们是对象而不是类。 这意味着只有一个实例存在并且由 Scala 本身创建。 如果要做依赖注入,那么需要依赖的东西必须由依赖注入框架创建。 因此,如果你想使用 guice,你需要使用一个类来为你的 fatory 建模。
我认为你对你的class PaymentHandlerFactory
是务实的方式,可能在大多数情况下都有效。 我会避免过早地使这过于通用。
如果你想让它更漂亮一点,你可以使用他们的AssistedInject 。
如果您遇到关于伴随对象上的 DI 的这个问题,请检查以下解决方法
DI 的好处是它将传播到这个伴随对象。
如果您在class Paypal
class BrainTree
和class BrainTree
上有一个伴生对象,如下所示:
@Singleton
class PayPal extends PaymentHandler{....}
object PayPal extends PayPal
@Singleton
class BrainTree extends PaymentHandler{....}
object BrainTree extends BrainTree
现在,我可以在 PaymentHandler 伴随对象中使用这些对象,如下所示:
// get the correct handler from factory
class PaymentHandler extends PaymentHandlerFactory(PayPal, BrainTree){...}
object PaymentHandler extends PaymentHandler
现在在任何类中,我们都可以使用PaymentHandler.get()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.