Reputation: 1240
I am using Scala + Play and the out of box Guice set up for dependency injection. I am also using Akka Persistence behind the scenes and would like to create a binding for a custom read journal that I can then inject around my application.
Unfortunately, the read journal constructor (which I do not control) requires an explicit reference to the actor system:
PersistenceQuery(actorSystem).readJournalFor[CustomReadJournal]("custom-key")
How do I get a reference to the underlying actorSystem
from within a binding definition class (Module
)? Is this possible? More generally, is it possible to define interdependent bindings (a la Scaldi?)
My Module
class entry currently looks like:
bind(classOf[CustomReadJournal]).toInstance(PersistenceQuery(<what do i put here?>).readJournalFor[CustomReadJournal]("custom-journal"))
Thanks in advance for the help!
Upvotes: 0
Views: 731
Reputation: 2841
If you need to do some kind of logic to create a dependency injection it is useful to use the @Provides annotation. For example:
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])
}
}
A useful thing to know is that @Provides
methods can themselves take parameters and get their arguments injected. For example:
@Provides
def provideThingNeedingParameter(param: P): ThingNeedingParam = {
new ThingNeedingParam(param)
}
Which is relevant to your situation I believe since you want to provide an actor system to an instance of some class.
// 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")
}
By creating an @Provides
annotated method for your CustomReadJournal you can avoid the bind
call from configure entirely and control the parameters a bit more. Also, if you need to, @Provides works with @Singleton. I haven't used Akka persistence, but I think this should help you
Upvotes: 2