如何创建依赖Guice(Play / Scala)绑定?

时间:2016-09-19 17:02:12

标签: scala playframework dependency-injection akka guice

我正在使用Scala + Play和开箱即用的Guice设置依赖注入。我也在幕后使用Akka Persistence,并希望为自定义读取日志创建一个绑定,然后我可以在我的应用程序周围注入。

不幸的是,读取日志构造函数(我无法控制)需要显式引用actor系统:

PersistenceQuery(actorSystem).readJournalFor[CustomReadJournal]("custom-key")

如何从绑定定义类(actorSystem)中获取对基础Module的引用?这可能吗?更一般地说,是否可以定义相互依赖的绑定(一个scaldi?)

我的Module班级条目目前如下:

bind(classOf[CustomReadJournal]).toInstance(PersistenceQuery(<what do i put here?>).readJournalFor[CustomReadJournal]("custom-journal"))

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

如果您需要执行某种逻辑来创建依赖注入,则使用@Provides注释很有用。例如:

trait MyProvider {
  @Provides
  def provideThing(): Thing = {
    //make the thing and return it
  }
}
class MyModule extends AbstractModule with MyProvider {
   override def configure() {
     bind(classOf[TraitYYY]).to(classOf[ClassThatTakesThingAsParameter])
   }
}

一个有用的事情是,@Provides方法本身可以获取参数并获取其参数。例如:

@Provides
def provideThingNeedingParameter(param: P): ThingNeedingParam = {
   new ThingNeedingParam(param)
}

这与您的情况有关我相信,因为您想演员系统提供给某个类的实例。

// You can use @Singleton with @Provides if you need this to be one as well!
@Provides
def provideActorSystem(app: Application): ActorSystem = {
    play.api.libs.concurrent.Akka.system(app)
}

@Provides
def providePersistenceQuery(actorSystem: ActorSystem): PersistenceQuery = {
    PersistenceQuery(actorSystem)
}

@Provides 
def provideCustomReadJournal(persistenceQuery: PersistenceQuery):CustomReadJournal = {
    persistenceQuery.readJournalFor[CustomReadJournal]("custom-key")    
}

通过为CustomReadJournal创建@Provides带注释的方法,您可以完全避免从配置调用bind并更多地控制参数。此外,如果您需要,@Provides可以使用@Singleton。我没有使用Akka持久性,但我认为这应该可以帮助你