当前位置: 首页 > 知识库问答 >
问题:

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

锺离穆冉
2023-03-14

我来自Java背景,也是函数范式的新手,所以请原谅我,我身上有OOP的味道。

我有一个特征名称付款处理程序

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{....}

直到这里一切都很好,但是当我想拥有多个基于付款方式的支付网关时,问题就来了。最初我写了一个像 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中实现这种工厂式的东西的正确方法是什么?

共有2个答案

景成和
2023-03-14

如果您遇到了关于伴随对象上的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

现在在任何类中,我们都可以使用PaymentHandler.get()

端木桐
2023-03-14

>

  • 无法注入伴随对象的原因是因为它们是对象而不是类。这意味着只有一个实例存在,并且是由 scala 本身创建的。如果要进行依赖注入,那么需要依赖的东西必须由依赖注入框架创建。因此,如果你想使用guice,你需要使用一个类来建模你的命运。

    我认为您对类PaymentHandlerWorks所做的是务实的方式,并且可能在大多数情况下都有效。我不想过早地将其变得过于通用。

    如果你想让它更容易一点,你可以使用他们的AssistedInject。

  •  类似资料:
    • 我要的不是意见而是事实 我正在尝试选择一个新的DI。我有一些Guice的经验。总的来说,我想说它的一个优点是,当从scala需要与Java集成时,Guice可以完成这项工作。所以对于互操作性来说,这是一个明显的优势。 如果我们抛开这个互操作性问题不谈,谁能给我简单的比较一下 scaladi,guice,Macwire? 我对了解烫伤症还是新手。我发现令人惊讶的一件事是必须通过隐式参数在喷油器周围移

    • 试图创建一个自定义的,我可以通过Jersey注入到我的资源中。 这在本问题的Java中有涉及。我已经阅读了有关这方面的文档,这些文档也是用Java编写的。最后,GitHub中的一些代码涵盖了相同的主题(通过Dropwizard完成)。 这将全部编译,但在运行时失败,出现以下异常 我不知道是我在向Scala的转换中犯了错误,还是我在注册绑定器时做了错误的事情。

    • 我是Scala和PlayFramework的新手,我正试图弄清楚如何进行依赖注入。我基本上想要一个将成为特征的文件,并将其注入控制器。我的问题是我的Controller类没有看到我的特性这是我的代码 个人资料性状 然后我尝试将其注入我的控制器 然而,我的控制器没有看到它,我试图按照这里的例子https://www . play framework . com/documentation/2.5 .

    • 我有一个非常简单的场景可以使用 DI 解决,但我无法找到合适的示例/文档来帮助我完成。我是Scala/Guice世界的新手。 当前组件看起来像这样 现在,我在Foo和Bar之间有一个依赖项。所以,通常代码看起来像这样 其中只是返回。当然,为了简洁起见,我删除了工厂/助手。 我意识到,当我使用“new”时,这已经脱离了DI范式。我希望确保可以基于参数将Bar注入FooImpl。有点像使用工厂。我们如

    • 我有一个控制器 服务接口 我想在我的控制器中使用@autowired来使用该服务,但当我运行应用程序时,我得到以下错误 org.springframework.beans.factory.beanCreationException:创建名为“demo application”的bean时出错:注入autowired依赖项失败;嵌套异常为org.SpringFramework.Beans.Facto

    • 在React中,想做依赖注入(Dependency Injection)其实相当简单。请看下面这个例子: // Title.jsx export default function Title(props) { return <h1>{ props.title }</h1>; } // Header.jsx import Title from './Title.jsx'; export defa