我正在遵循com.googlegroups.google-guice http://markmail.org/message/ljnhl6rstverrxuj
的建议Well, it's actually almost as referred to you in the link from the other answer:
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
class MyClient {
@Inject val toBeInjected: AnotherClass = toBeInjected // !!
}
trait ServiceInjector {
ServiceInjector.inject( this )
}
object ServiceInjector {
private val injector = Guice.createInjector( Array[Module]( new YourModule ) )
def inject( obj: AnyRef ) = injector.injectMembers( obj )
}
Usage:
val client = new MyClient with ServiceInjector
or:
class InjectedMyClient extends MyClient with ServiceInjector
但是我对Scala很新,并试图找出如何使用以下模式进行依赖注入,当Guice模块本身需要引用从其他地方传入的实例时。
但是因为traits不能有构造函数,Companion对象看起来我也不会被搞砸了?
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之后,但我似乎无法找到将它们传递给对象的方法。
答案 0 :(得分:1)
由于我正在使用Scala,因此我不再使用DI框架,因为Scala已经具有原生的DI支持。这称为蛋糕模式。有很多可用的资源,例如blogpost from Cake Solutions。
在ScalaDays 2014和Devoxx 2014上,Dick Wall还展示了一种更轻量级的DI解决方案,他称之为Parfait Pattern。这两场会谈都可以在Parleys.com上查看
如果你真的想使用DI框架,Scaldi是一个很好看的Scala框架,它使用Scala功能,当然你也可以继续使用Spring或Guice。
答案 1 :(得分:1)
我不确定这个:
@Inject val toBeInjected: AnotherClass = toBeInjected
根据我的经验不起作用。它必须是var
而非val
和初始值null
。
@Inject var toBeInjected: AnotherClass = null
我创建了demo on GitHub这是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
可以使用相同的技术。