是否有一种很好的Play2方式通过Guice在Play插件中注入实例 [英] Is there a nice Play2 way of injecting instances in Play Plugins with Guice

查看:118
本文介绍了是否有一种很好的Play2方式通过Guice在Play插件中注入实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试弄清楚如何将我的带有Google Guice的类注入play.api.Plugin中. 我已经实现了Guice与我的控制器一起工作,并且效果很好.

I'm trying to figure out how to inject my classes with Google Guice into a play.api.Plugin. I have implemented Guice to work with my controllers and it works great.

我使用:

"com.google.inject" % "guice" % "4.0-beta",
"com.tzavellas" % "sse-guice" % "0.7.1"

当需要一个Controller实例时,由于注入器的作用,Global中的getControllerInstance方法将加载适当的实现.

When a Controller instance is needed the getControllerInstance method in Global will load the appropriate implementation thanks to the injector.

全局:

object Global extends GlobalSettings {

  /**
   * Currently we only want to load a different module when test.
   */
  private lazy val injector = {
    Logger.info("Is Test: "+Play.isTest)

    Play.isTest match {
      case true => Guice.createInjector(new TestModule)
      case false => Guice.createInjector(new CommonModule)
    }
  }    

  override def onStart(app: Application) {
    Logger.info("Application has started")
  }

  override def onStop(app: Application) {
    Logger.info("Application shutdown...")
  }

  override def getControllerInstance[A](clazz: Class[A]) = {
    Logger.info("getControllerInstance")
    injector.getInstance(clazz)
  }    
}

常用:

package modules

import com.tzavellas.sse.guice.ScalaModule
import services.{CallServiceImpl, CallService}

/**
 * User: jakob
 * Date: 11/5/13
 * Time: 10:04 AM
 */
class CommonModule extends ScalaModule {
  def configure() {
    bind[CallService].to[CallServiceImpl]
  }
}

class TestModule extends ScalaModule {
  def configure() {
    // Test modules!
  }
}

控制器:

@Singleton
class StatsController @Inject()(callService: CallService) extends Controller with securesocial.core.SecureSocial with ProvidesHeader  {

    def doSomething = {
        callService.call()
    }   
}

现在,我想将相同的服务注入到我的插件中,但是由于插件未随 getControllerInstance

Now I would like to inject the same service into my Plugin, but I can't make use of the Global implementation since the plugins do not load with the getControllerInstance

class CallerPlugin (application: Application) extends Plugin {

  val secondsToWait = {
    import scala.concurrent.duration._
    10 seconds
  }

  val defaultInterval = 60
  val intervalKey = "csv.job.interval"
  val csvParserEnabled = "csv.job.enabled"
  val newDir = "csv.job.new.file.path"
  val doneDir = "csv.job.done.file.path"

  var cancellable: Option[Cancellable] = None

  override def onStop() {
    cancellable.map(_.cancel())
  }

  override def onStart() {

    // do some cool injection of callService here!!!

    import scala.concurrent.duration._
    import play.api.libs.concurrent.Execution.Implicits._
    val i = current.configuration.getInt(intervalKey).getOrElse(defaultInterval)

    cancellable = if (current.configuration.getBoolean(csvParserEnabled).getOrElse(false)) {
      Some(
        Akka.system.scheduler.schedule(0 seconds, i minutes) {
            callService.call()

        })
    } else None
  }
}

我想应该以某种方式在onStart方法中实现注入,并且可能有一些不错的简便方法,但是我无法弄清楚. 谢谢!

I guess there should be a way of implementing the injection in the onStart method somehow and there is probably some nice easy way of doing this but I can't figure it out. Thank you!

推荐答案

如果我正确理解了您的问题,则您想知道如何实例化和使用Guice注入器.好吧,这真的很简单:

If I understood your question correctly, you're wondering how to instantiate and use a Guice injector. Well it's really simple:

val injector = Guice.createInjector(new CommonModule)
val callService = injector.getInstance(classOf[CallService])

这样,您就有一个CallServiceImpl的实例.如果您查看Global.scala,这正是您在其中所做的.我还没有使用Play插件,所以不知道如何实例化它们,但是我认为,更惯用的方式是将CallService作为参数插入CallerPlugin(就像您对控制器所做的一样).这样,您就可以将依赖项注入的责任传递到树上,这样,理想情况下,您将只能使用一个注入器(可能在Global中).

And like that you have an instance of CallServiceImpl. If you look at your Global.scala, this is exactly what you do there. I haven't used Play plugins, so I'm not sure how you instantiate them, but I think a more idiomatic way would be, instead of putting it in plugin's onStart, to inject this CallService as a parameter to CallerPlugin (like you do for the controller). That way you could pass the responsibility of dependency injection down the tree, so that ideally you would end up with only one injector (probably in Global).

这篇关于是否有一种很好的Play2方式通过Guice在Play插件中注入实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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