2017-04-13 147 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