Tec*_*mag 7 annotations scala inject playframework
我正在看看来自play-mailer的scaly代码示例:https://github.com/playframework/play-mailer
它基本上是这样的:
class MyComponent @Inject() (mailerClient: MailerClient) {
...
}
Run Code Online (Sandbox Code Playgroud)
很简单,它编译时没有顺从
然后我尝试"调用"它然而似乎没有办法满足编译器或获得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
Run Code Online (Sandbox Code Playgroud)
我可能因为这个而接近了:
这表明通过@Inject
从构造函数中删除并将其放在字段上,以下语法可能会起作用.
@Inject var mailerClient: MailerClient = null
Run Code Online (Sandbox Code Playgroud)
但是,当我们尝试运行任何需要该引用的东西时,我们仍然会得到null.
我正在阅读@Inject上可以找到的所有内容
([警告] [咆哮]我不是这样的编译器魔法的粉丝这个确切的原因 - 伏都教魔法是美妙的,直到它停止工作,然后似乎没有人知道如何解决它.[/ rant] [/警告] )
但我真正想知道的是如何正确,安全和有效地使用它.
Mar*_*ijn 10
既然你在原来的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 {
...
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,FooClass
是要注入控制器的依赖项的类名.让我们说FooClass
将Play Application
作为一个依赖,这将被注入,因为Play提供了几个预先绑定的预设,Application
但也ActorSystem
.
这是可能的,因为玩!框架使用DependencyInjectedRoutes
.如果您要在Controller之外创建一个Actor,则需要在模块类中指定它,但在此链接和此链接中对此进行了解释.
还有一个概念是Traits
在控制器内部使用,然后将特性与实现类连接在一起,但我认为现在有点太复杂了.
如果你想要这种编写应用程序的方法有一些好处和成功的故事,这里有一个很好的资源:https://softwareengineering.stackexchange.com/a/19204/164366
如果你想要阅读这个概念:
我希望这能解决问题!如果您有疑问,请询问!
小智 0
这不是一个 scala 问题,而是一个 DI 问题。您应该阅读一些guice文档。
在 Play 2.4.x 中,您需要使用依赖注入(https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection)来实现您的目标。
你的 AnObject 应该是:
@Singleton class AnObject @Inject()(mailer:MyComponent){
def sendEmail = mailer.doStuff
}
Run Code Online (Sandbox Code Playgroud)