我来自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。 最初我写了一个像
这样的PaymentHandlerFactoryclass 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对象。现在我脑子里有两个问题。
答案 0 :(得分:1)
无法注入伴随对象的原因是因为它们是对象而不是类。这意味着只存在一个实例,并且由scala本身创建。如果要进行依赖项注入,则必须通过依赖项注入框架创建需要依赖项的事物。因此,如果你想使用guice,你需要使用类来模拟你的死亡。
我认为您对class PaymentHandlerFactory
所做的是务实的方式,并且可能在大多数情况下有效。我不会过早地使这个过于通用。
如果你想让它变得更加明智,你可以使用他们的AssistedInject。
答案 1 :(得分:0)
如果您对伴随对象上的DI提出了疑问,请检查以下变通方法
DI的好处是它将被传播到该伴随对象。
如果您在class Paypal
和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()