繁体   English   中英

Scala - 伴随对象中的依赖注入

[英]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 对象。 现在我脑子里有两个问题。

  1. 为什么我们不能在 Scala 中注入伴生对象?
  2. 在 Scala 中实现这样的工厂的正确方法是什么?
  1. 不能注入伴生对象的原因是因为它们是对象而不是类。 这意味着只有一个实例存在并且由 Scala 本身创建。 如果要做依赖注入,那么需要依赖的东西必须由依赖注入框架创建。 因此,如果你想使用 guice,你需要使用一个类来为你的 fatory 建模。

  2. 我认为你对你的class PaymentHandlerFactory是务实的方式,可能在大多数情况下都有效。 我会避免过早地使这过于通用。

如果你想让它更漂亮一点,你可以使用他们的AssistedInject

如果您遇到关于伴随对象上的 DI 的这个问题,请检查以下解决方法

  • 使用带有 DI 的相应类
  • 在这个类上创建一个伴生对象

DI 的好处是它将传播到这个伴随对象。

如果您在class Paypal class BrainTreeclass 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM