2013-12-13 104 views
3

這將是一個關於如何讓綁定工作的問題,但是在清理我的示例以準備發佈後,我已經設法使其工作 - 問題是我不知道爲什麼這個工程:用Scala Guice綁定一個對象到一個對象

import org.specs2.mutable._ 
import com.google.inject.{ Inject, Module, Binder, Guice } 
import net.codingwell.scalaguice.ScalaModule 

object InjectorSpec extends Specification { 
    val injector = Guice.createInjector(new ScalaModule() { 
    def configure() { 
     bind[Message].toInstance(MessageImpl) 
     bind[MessageService.type].toInstance(MessageService) // This line makes it work? 
    } 
    }) 

    trait Message { 
    val body: String 
    } 

    object MessageImpl extends Message { 
    val body: String = "Hello!" 
    } 

    object MessageService { 
    @Inject 
    val message: Message = null 

    def get = message.body 
    } 

    "MessageService" should { 
    "Inject Message Implementation" in { 
     MessageService.get mustEqual "Hello!" 
    } 
    } 
} 

最初我只是綁定類型被注入(注入MessageImpl消息)。一路上,我拿起了服務的第二個綁定,沒有注入(所以我不明白綁定是必需的)。任何人都可以解釋這裏發生了什麼,如果這是繼續進行的正確方法?

+0

https://pbs.twimg.com/media/ A5HdRB-CIAAM3Ri.png:大* scnr * –

+0

@StefanKunze確切! :) – matthewrk

回答

3

所以問題在於,guice不會搜索您的程序,並找到您在任何地方加載的任何類中的所有@Inject點。相反,需要給它一些路徑來找到你想要注入東西的對象。通常,這是通過使用吉斯的方式照顧,因爲標準模式是:

val injector = Guice.createInjector(/* stuff */) 
val main = injector.getInstance(classOf[Main]) 
main.mainMethod() 

吉斯上的Main實例,你問它做/獲取,並在所有遞歸執行注射執行注射東西@Inject編成main

就你而言,其中一個陳述也有效;我說「其中之一」,因爲雖然我可以告訴你如何注入到java我不完全清楚scala編譯器如何將scala伴隨對象編譯爲java類。 (也就是說,我不知道是否message通過一些線程Singleton模式最終是在Java級別上稱爲MessageService$類或實例變量靜態變量,與被實例化MessageService$只有一次)

requestInjection(MessageService) 
requestStaticInjection(MessageService.type) 

toInstance聲明起作用的原因是Guice在創建注射器時自動對傳遞到toInstance的所有注射進行注射。 (如果你創建一個「生產模式」注射器,所有東西都綁定爲單件,所以約束.asEagerSingleton也將在注射器上進行注射)

+0

啊哈,我認爲這將是沿着這些線。 @Inject和requestInjection的使用似乎比我的代碼基礎上直接引用注入器更清晰了? – matthewrk

+2

那麼,理想情況下,你只需要引用'injector'一次,只爲你的主類調用'getInstance'一次,然後所有東西都從那裏注入。 斯卡拉伴侶對象將事情搞砸了一點,因爲它們是從java的角度來看這些在Guice之外創建的單例對象。現在,這很好,但是當你有這些Guice沒有創建的東西時,麻煩來了,你想讓Guice注入東西。我不喜歡scala-guice風格(我所有的Guice經驗都是用java編寫的),但我認爲解決方案是永遠不要將@Inject注入到伴隨對象中。 –

+1

也就是說,如果你需要'@Inject'的singleton對象,使它們成爲'trait's或'class'es並綁定它們.in(classOf [Singleton])'在Guice裏面;不要在需要注入東西的地方使用伴侶對象。 –

相關問題