Scala(Play 2.4.x)如何使用@inject()注释调用类

我正在看看来自play-mailer: https://github.com/playframework/play-mailer的scaly代码示例

它基本上是这样的:

class MyComponent @Inject() (mailerClient: MailerClient) {
   ...
}

足够简单,它编译不符合要求

然后我尝试“调用”它然而似乎没有办法满足编译器或获得mailerClient的工作实例.

object AnObject {
  val mailer = new MyComponent
  def sendEmail = mailer.doStuff
}

[info] Compiling 1 Scala source to ...
[error] /SomeOne/SomePath/SomeFile.scala:30: not enough arguments for constructor MyComponent: (mailerClient: play.api.libs.mailer.MailerClient) MyComponent.
[error] Unspecified value parameter mailerClient.
[error]   val mailer = new MyComponent
[error]                ^
[error] one error found
[error] (compile:compileIncremental) Compilation Failed

我可能因为这个而接近了:

How does @Inject in Scala work

这表明通过从构造函数删除@Inject并将其放在字段上,以下语法可能会起作用.

@Inject var mailerClient: MailerClient = null

然而,当我们尝试运行任何需要该引用的东西时,我们仍然会得到null.

我正在阅读@Inject上可以找到的所有内容

([警告] [咆哮]我不是这样的编译器魔法粉丝这个确切的原因 – 伏都教魔法很棒,直到它停止工作然后似乎没有人知道如何解决它.[/ rant] [/警告] )

但我真正想知道的是如何正确,安全和有效地使用它.

解决方法

由于您在原始的GitHub仓库上关闭了您的问题,我不知道这个答案是否仍然是必要的,但由于您不完全理解DI框架的使用,我发现学习这项技能非常重要,我会试着在这里解释并列出一些好处.

首先,实例化实例的方式并没有给DI框架注入依赖关系的机会.由于new是一个语言关键字,因此DI无法干预,并且无法注入您所需的类依赖关系.如何完成是通过构造函数或字段注入.我将主要关注构造函数注入,因为它是scala世界中的“标准”.

如果使用@Injected批注指定构造函数参数,则基本上是告诉DI框架从容器中解析此依赖关系. DI框架在其容器内查找该对象的条目.如果它不存在,它将创建它(并在进程中解析其依赖关系),如果它使用@Singleton注释,也保存此实例以供将来使用.大多数DI框架要求您在大多数情况下指定起始类,但因为您正在使用Play!这个框架没有必要.如果要在控制器中使用特定模块,可以执行以下操作:

import javax.inject.Inject

import play.api.mvc.Controller

class Test @Inject() (val dependency: FooClass) extends Controller {
  ...
}

在这种情况下,FooClass是要注入控制器的依赖项的类名.假设FooClass将Play的应用程序作为依赖项注入,因为Play提供了几个预绑定的预设,如Application,还有ActorSystem.

这是可能的,因为玩! Framework使用DependencyInjectedRoutes.如果您要在Controller之外创建一个Actor,则需要在模块类中指定它,但在此linklink中对此进行了解释.

还有一个概念是在控制器中使用Traits,然后将特性与实现类连接起来,但我认为现在有点太复杂了.

如果你想要这种编写应用程序的方法有一些好处和成功的故事,这里有一个很好的资源:https://softwareengineering.stackexchange.com/a/19204/164366

如果你想要阅读这个概念:

> https://www.playframework.com/documentation/2.4.x/ScalaAkka
> https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection
> https://www.playframework.com/documentation/2.4.x/ScalaCompileTimeDependencyInjection

我希望这能解决问题!如果您有疑问,请询问!

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...