如何使用scala将实例传递给ServiceInjector特性?

如何使用scala将实例传递给ServiceInjector特性?,scala,guice,Scala,Guice,我遵循com.googlegroups.google-guice的建议 但我对Scala非常陌生,我正在尝试解决如何在Guice模块本身需要引用从其他地方传入的实例时使用以下模式进行依赖项注入 但是既然traits不能有构造函数,同伴对象也不能,那我就完蛋了 package au.id.rleach.overmind.guice import com.google.inject.{Provides, Guice, Binder, Module} import org.slf4j.Logger

我遵循com.googlegroups.google-guice的建议

但我对Scala非常陌生,我正在尝试解决如何在Guice模块本身需要引用从其他地方传入的实例时使用以下模式进行依赖项注入

但是既然traits不能有构造函数,同伴对象也不能,那我就完蛋了

package au.id.rleach.overmind.guice

import com.google.inject.{Provides, Guice, Binder, Module}
import org.slf4j.Logger
import org.spongepowered.api.service.ServiceManager
import org.spongepowered.api.world.TeleportHelper
import org.spongepowered.api.{GameRegistry, Game}
import org.spongepowered.api.plugin.PluginManager
import org.spongepowered.api.scoreboard.ScoreboardBuilder
import org.spongepowered.api.service.event.EventManager

class OModule(val game: Game, val logger: Logger, val pluginManager: PluginManager, val serviceManager: ServiceManager, val eventManager: EventManager, val gameRegistry: GameRegistry, val teleportHelper: TeleportHelper) extends Module {

  override def configure(binder: Binder): Unit = {
    binder.bind(classOf[Game]).toInstance(game)
    binder.bind(classOf[Logger]).toInstance(logger)
    binder.bind(classOf[PluginManager]).toInstance(pluginManager)
    binder.bind(classOf[ServiceManager]).toInstance(serviceManager)
    binder.bind(classOf[EventManager]).toInstance(eventManager)
    binder.bind(classOf[GameRegistry]).toInstance(gameRegistry)
    binder.bind(classOf[TeleportHelper]).toInstance(teleportHelper)
    //bind(classOf[File]).annotatedWith(new ConfigDirAnnotation(true)).toInstance(Loader.instance.getConfigDir)
  }
}

trait ServiceInjector {
  ServiceInjector.inject(this)
}

object ServiceInjector {
  private val injector = Guice.createInjector(
//####
    new OModule()//compilation error.
//####
  )
  def inject(obj: AnyRef) = injector.injectMembers(obj)
}

我意识到对象在第一次使用时正在初始化,那是在我有一个实例副本要传递给OModule之后,但我似乎找不到一种方法将它们传递给对象。

因为我使用Scala,我不再喜欢使用DI框架,因为Scala已经在本质上支持DI。这就是所谓的蛋糕图案。在这方面有很多可用的资源,像这样

在ScalaDays 2014和Devxx 2014上,Dick Wall还介绍了一种更轻量的DI解决方案,他称之为冻糕模式。两次会谈都可以在Parleys.com上查看


如果您真的想使用DI框架,BushTi是一个利用Scala功能的漂亮Scala框架,但当然您也可以继续使用Spring或Guice。

我不确定这一点:

@Inject val toBeInjected: AnotherClass = toBeInjected
以我的经验是行不通的。它需要是
var
而不是
val
,并且初始值
null

@Inject var toBeInjected: AnotherClass = null
我创建了一个
Play Scala
模板,其中
index
方法更改如下:

class Application extends Controller {

  @Inject var ws: WSClient = null

  def index = Action.async {
    ws.url("http://google.com").get.map(r => Ok(r.body))
  }

}

这很有效。注入到字段而不是作为构造函数参数的。同样的技术也可以用于traits
traits

我之所以使用Guice是为了与Java兼容,而且我已经通过Spongapi(minecraft服务器模块)的Guice注入获得了实例。注入val效果很好,这不是我遇到的问题。问题是我无法传递模块需要的实例,并且我无法访问用于获取插件类中实例的注入器。我最终为对象中的模块创建了一个setter,但我也不太喜欢这个解决方案,所以希望在堆栈溢出上发布更好的内容。
@Inject val toBeInjected:AnotherClass=toBeInjected
class Application extends Controller {

  @Inject var ws: WSClient = null

  def index = Action.async {
    ws.url("http://google.com").get.map(r => Ok(r.body))
  }

}