斯卡拉(播放的2.4.x)如何调用类@Inject()注释 [英] Scala (Play 2.4.x) How to call a class with @inject() annotation

查看:178
本文介绍了斯卡拉(播放的2.4.x)如何调用类@Inject()注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我期待在从播放邮件的鳞屑code例如: https://开头的github .COM / playframework /播放,邮件<​​/A>

I'm looking at the scaly code example from play-mailer: https://github.com/playframework/play-mailer

它去基本上是这样的:

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

足够简单,它编译没有符合

simple enough and it compiles without compliant

然后我试着然而,呼叫,并似乎没有被满足编译器或获取mailerClient的工作实例的方式。

Then I try to "call" it however and there doesn't appear to be a way to satisfy the compiler OR get a working instance of 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

不过,我觉得我可能已经得到了接近得益于这样的:

I though I might have gotten close thanks to this:

如何@Inject在斯卡拉工作

这表明以下语法可能会被从构造函数删除 @Inject ,并把它放在一个领域的工作。

Which indicated that the following syntax might work by removing the @Inject from the constructor and placing it on a field.

@Inject var mailerClient: MailerClient = null

但是,我们尝试运行任何需要的参考,我们仍然得到空的时刻。

However the moment we try to run anything that needs that reference we still get null.

我在读的一切,我可以找到@Inject

I'm reading everything I can find on @Inject

([警示] [咆哮]我不是这个确切原因的编译器魔术这样的风扇 - 巫术是美好的,直到它停止工作,然后,似乎没有人对如何解决任何想法它[/咆哮] [/警告])

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

but what I really want to know is how to use it properly, safely and effectively.

推荐答案

由于您关闭您的问题对原GitHub库,我不知道这个答案仍然是必要的,但因为你没有完全了解使用一个DI框架,我觉得非常重要的学习这个技能,我会试着在这里解释它,并列出一些好处。

Since you closed your issue on the original GitHub repo, I don't know if this answer is still necessary but since you don't fully understand the use of a DI framework and I find it incredibly important to learn this skill, I'll try to explain it here and list some benefits.

首先,你实例化你的实例并不会给DI框架有机会注入你的依赖的方式。由于是一门语言的关键字,DI不能干涉,你需要为你的类的依赖性,不能注射。它是如何做是通过构造函数或字段注入。我将主要集中在构造函数注入,因为这是在世界上阶的标准。

First off, the way you are instantiating your instance doesn't give the DI framework a chance to inject your dependencies. Since new is a language keyword, DI can't interfere and the dependencies you need for your class can't be injected. How it is done is through constructor or field injection. I'll mainly focus on constructor injection because that is "standard" in the scala world.

如果您指定的 @Injected 注释的构造函数的参数,你基本上是告诉DI框架来解决从容器这种依赖性。该DI框架去,并查找其容器内的那个对象的条目。如果不存在,它会创建它(并解决其在进程的依赖),如果它与 @Singleton 注释还可以节省这种情况下以备将来使用。大多数DI框架,要求你在大多数情况下,指定一个起始类,但由于您使用的游戏!框架,这是没有必要的。当你想使用一个特定模块控制器里面,你可以这样做:

If you specify a constructor argument with the @Injected annotation, you are basically telling the DI framework to resolve this dependency from the container. The DI framework goes and looks for an entry of that object inside its container. If it doesn't exists, it will create it (and resolve its dependencies in the process) and if it's annotated with @Singleton also save this instance for future use. Most DI frameworks require you to specify a starting class in most cases but because you are using Play! Framework this is not necessary. When you want to use a particular module inside your controller you can do this:

import javax.inject.Inject

import play.api.mvc.Controller

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

在这种情况下, FooClass 是要注入到控制器的依赖的类名。比方说, FooClass 具有播放的应用作为一个依赖,这将被注入,因为游戏提供了一些pre-保税$ p $的pset像应用 ActorSystem

In this case FooClass is the class name of the dependency you want to inject into your controller. Let's say FooClass has Play's Application as a dependency this will be injected, because Play provides a couple pre-bonded presets like Application but also ActorSystem.

这是可能的,因为游戏!框架使用 DependencyInjectedRoutes 。如果你到一个控制器之外创建一个演员,你需要指定一个模块类中但在此说明的链接链接

This is possible because Play! Framework uses DependencyInjectedRoutes. If you were to create an Actor outside of an Controller you would need to specify that inside a module class but that is explained in this link and this link.

还有使用性状控制器内,然后以后将它们连接起来的特点与实现类的概念,但我认为这是一个有点太复杂了,现在。

There is also a concept of using Traits inside your controller and then later on wiring together the traits with the implementation classes but I think that is a bit too complicated for now.

如果你想要一些好处和更迭的故事来书写应用这种方法,这里是一个很好的资源:<一href=\"http://programmers.stackexchange.com/a/19204/164366\">http://programmers.stackexchange.com/a/19204/164366

If you want some benefits and succes stories to this method of writing applications, here is a good resource: http://programmers.stackexchange.com/a/19204/164366

如果你想要的东西,以这个概念为:

If you want something to read on this concept:

  • 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

我希望这将清除的东西了!如果您有疑问,请不要问!

I hope this clears things up! If you have question, please do ask!

这篇关于斯卡拉(播放的2.4.x)如何调用类@Inject()注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆