2017-04-13 186 views
0

調用注入斯卡拉類我在玩下面的類斯卡拉是注入其他類:從阿卡演員

class MainEtl2 @Inject() (ic: injectedClass) { 
    def run (option: String) = { 
     ic.method1() 
     // ... some code 
    } 
} 

我需要調用方法run在阿卡演員。這是我的嘗試,假設當調用MainEtl2吉斯將注入injectedClass

class MainEtl extends Actor { 

    @Inject val me2 : MainEtl2 

    def receive = { 
    case option: String => {   
     val x = me2.run(option) 
     // ... more code 
     } 
    } 
    } 

MainEtl類不與followint錯誤編譯:

class MainEtl needs to be abstract, since value me2 is not defined 

如何使這項工作?

+0

你有沒有嘗試在'MainEtl'的構造函數中注入'me2'? –

+0

是的,看到我的評論以下答案 – ps0604

回答

3

我會根據Play documentation提出這樣的解決方案。定義你的演員在這樣的方式:通過增加

play.modules.enabled += "some.package.AkkaBindings" 

現在你

class AkkaBindings extends AbstractModule with AkkaGuiceSupport { 
    bindActor[MainEtl]("mainEtl") 
} 

註冊此模塊中application.conf:

class MainEtl @Inject() (me2: MainEtl2) extends Actor { 
    def receive = { 
    case option: String => {   
     val x = me2.run(option) 
    } 
    } 
} 

定義與阿卡支持播放模塊,並結合命名演員可以通過名稱參考注入您的演員:

class Scheduler @Inject()(@Named("mainEtl") mainEtl: ActorRef) { 
    //some code 
    val scheduler = QuartzSchedulerExtension(system) 
    scheduler.schedule("dailyproc", mainEtl, "abc", None) 
} 
+0

非常感謝,這工作。唯一需要注意的是,如果您按照[此處](https://www.playframework.com/documentation/2.5.x/ScalaDependencyInjection#programmatic-bindings)的說明擴展'AbstractModule',則需要定義一個配置方法。 – ps0604

1

我會嘗試注入MainEtl2類似CountingService如何在this example注:

class MainEtl @Inject() (me2: MainEtl2) extends Actor { 
    def receive = { 
    case option: String => {   
     val x = me2.run(option) 
     // ... more code 
    } 
    } 
} 
+0

我在MainEtl中注入了MainEtl2,但當我嘗試實例化actor時出現錯誤:'val actor = system.actorOf(Props [MainEtl])'throws:'Error injecting constructor ,java.lang.IllegalArgumentException:在類MainEtl上找不到匹配參數的匹配構造函數[]' – ps0604

+0

您是否遵循上述示例應用程序如何使用[scala-guice]配置'CountingActor'(https://github.com/rocketraman/activator -akka-scala-guice/blob/master/src/main/scala/sample/SampleModule.scala)並從其Main'應用程序實例化actor?自從我測試了Lightbend的示例應用程序以來,它已經有一段時間了,但它確實按照廣告方式工作。 –

+0

我試圖關注這個項目,但它太複雜了,我正在尋找的是發送消息給有注入對象的actor,我想沒有簡單的方法來做到這一點。 – ps0604

0

雖然您指定@Inject註解,你仍然需要其同時注入依賴吉斯將覆蓋初始值,那麼試試這個,

class MainEtl extends Actor { 

    @Inject val me2 : MainEtl2 = null //initial value. 

    def receive = { 
    case option: String => {   
     val x = me2.run(option) 
     // ... more code 
     } 
    } 
    } 
+0

這沒有奏效,'me2'爲空,無法運行該方法。這是我得到的錯誤:'[error] aaOneForOneStrategy - null java.lang.NullPointerException:null at tasks.etl.MainEtl $$ anonfun $ receive $ 1.applyOrElse(MainEtl.scala:17) at akka.actor .Actor $ class.aroundReceive(Actor.scala:484)' – ps0604

+0

您是如何創建MainEtl實例的?它應該通過Guice創建,如果你已經用新創建了它,注入將不會在該類中工作。 – vsbehere

+0

MainEtl啓動正常,問題出現在調用「me2.run」時。我使用'akka-quartz-scheduler'來啓動MainEtl:'val scheduler = QuartzSchedulerExtension(system)''val receiver = system.actorOf(Props [MainEtl])'scheduler.schedule(「dailyproc」,receiver,「abc」 ,None)' – ps0604