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

问题描述 投票:1回答:2

我来自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中实现类似工厂的正确方法是什么?
scala playframework dependency-injection guice
2个回答
1
投票
  1. 之所以无法注入伴随对象,是因为它们是对象而不是类。这意味着仅存在一个实例,并且由scala本身创建。如果要进行依赖项注入,则必须由依赖项注入框架创建需要依赖项的事物。因此,如果您想使用guice,则需要使用一个类来为您的虚构模型建模。

  2. 我认为您对class PaymentHandlerFactory所做的工作是务实的方式,可能在大多数情况下都可以使用。我不要过早地使它变得太通用。

如果您想使其更具趣味性,可以使用其AssistedInject


0
投票

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

  • 将对应的类与DI一起使用
  • 在此类上创建一个伴随对象

DI的好处是它将被传播到此伴随对象。

如果您在class Paypalclass 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
© www.soinside.com 2019 - 2024. All rights reserved.