Rhy*_*ury 28 scala object guice playframework
我一直在玩Play!框架为斯卡拉现在将近一年.我目前正在使用2.5.x版.
我知道Play中控制器的发展以及开发人员如何被迫远离静态object
路由.
我也知道Guice在游戏中的用法.
如果您下载激活器并运行:
activator new my-test-app play-scala
Run Code Online (Sandbox Code Playgroud)
Activator将为您生成模板项目.我的问题是围绕该模板的这个文件.
我的测试,应用程序/应用程序/服务/ Counter.scala
package services
import java.util.concurrent.atomic.AtomicInteger
import javax.inject._
/**
* This trait demonstrates how to create a component that is injected
* into a controller. The trait represents a counter that returns a
* incremented number each time it is called.
*/
trait Counter {
def nextCount(): Int
}
/**
* This class is a concrete implementation of the [[Counter]] trait.
* It is configured for Guice dependency injection in the [[Module]]
* class.
*
* This class has a `Singleton` annotation because we need to make
* sure we only use one counter per application. Without this
* annotation we would get a new instance every time a [[Counter]] is
* injected.
*/
@Singleton
class AtomicCounter extends Counter {
private val atomicCounter = new AtomicInteger()
override def nextCount(): Int = atomicCounter.getAndIncrement()
}
Run Code Online (Sandbox Code Playgroud)
您还可以在此文件中查看其用法:
我的测试,应用程序/应用/控制器/ CountController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import services.Counter
/**
* This controller demonstrates how to use dependency injection to
* bind a component into a controller class. The class creates an
* `Action` that shows an incrementing count to users. The [[Counter]]
* object is injected by the Guice dependency injection system.
*/
@Singleton
class CountController @Inject() (counter: Counter) extends Controller {
/**
* Create an action that responds with the [[Counter]]'s current
* count. The result is plain text. This `Action` is mapped to
* `GET /count` requests by an entry in the `routes` config file.
*/
def count = Action { Ok(counter.nextCount().toString) }
}
Run Code Online (Sandbox Code Playgroud)
这意味着每个具有构造函数的控制器都@Inject() (counter: Counter)
将接收相同的实例Counter
.
所以我的问题是:
为什么使用@Singleton
然后将@Inject
其用于控制器,对于此示例,您可以只使用Scala对象?
它的代码少得多.
例:
我的测试,应用程序/应用程序/服务/ Counter.scala
package services
trait ACounter {
def nextCount: Int
}
object Counter with ACounter {
private val atomicCounter = new AtomicInteger()
def nextCount(): Int = atomicCounter.getAndIncrement()
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
我的测试,应用程序/应用/控制器/ CountController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import services.{Counter, ACounter}
/**
* This controller demonstrates how to use dependency injection to
* bind a component into a controller class. The class creates an
* `Action` that shows an incrementing count to users. The [[Counter]]
* object is injected by the Guice dependency injection system.
*/
@Singleton
class CountController extends Controller {
//depend on abstractions
val counter: ACounter = Counter
def count = Action { Ok(counter.nextCount().toString) }
}
Run Code Online (Sandbox Code Playgroud)
有什么不同?是注射的首选,为什么?
nat*_*bbs 19
注射是首选方式吗?一般是的
使用依赖注入的几个优点:
Counter
.
object
,则必须更改控制器以指向不同的实现.例如Counter2.nextCount().toString
Counter
你内心正在WS
打电话.这可能会导致单元测试的一些困难.如果您正在使用Guice的依赖注入,则可以覆盖之间的绑定,Counter
并AtomicCounter
指向Counter
您专门为测试编写的脱机版本.有关使用Guice进行Play测试的详细信息,请参阅此处.另请参阅Play用于迁移到DI 的动机.
我说一般是因为我看到使用Spring和其他Java框架的依赖注入非常错误.我会说你应该使用自己的判断,但在使用DI for Play时会犯错误.
也许是因为Scala的单例对象不能有参数?例如,如果您有一个注入了DAO的服务类,并且您想在控制器中使用服务,则必须注入它.最简单的方法(IMO)是DI with Guice ...此外,您可以将您的依赖项放在一个地方(模块)等...
归档时间: |
|
查看次数: |
6367 次 |
最近记录: |