Guice Modules for Play apps


As a former Java / Spring developer I liked the concept of configuration classes (i.e. Java classes annotated with the Spring @Configuration annotation).

I recently started to work with Play 2.3.x and Guice and one smell that I immediately found was the duplication in creating RedisClient objects.

Basically each Dao was reading the configuration and creating its own copy of the bean. While most of the RedisClient(s) were configured slightly differently, some Daos contained literally copy-and-paste code.

After some research I came across the Guice AbstractModule class and the @Provides annotation. For those of you familiar with Java + Spring a Guice Module is similar to a Java class annotated with the Spring @Configuration.

Below there is an example of the MyRedisService that relies on two RedisClients. The two RedisClients are configured in the Config Guice Moducle and individuated by their names.

The Config Module:

package config
import akka.actor.ActorSystem
import com.example.driver.RedisClient
import com.google.inject.name.Named
import com.google.inject.{AbstractModule, Provides}
class Config extends AbstractModule {
override def configure(): Unit = {
// Just make compiler happy
}
@Provides
@Named("myDbOne")
def dbOneRedisClient(actorSystem: ActorSystem): RedisClient = {
new RedisClient("localhost", 1234)(actorSystem)
}
@Provides
@Named("myDbTwo")
def dbTwoRedisClient(actorSystem: ActorSystem): RedisClient = {
new RedisClient("localhost", 5678)(actorSystem)
}
}

view raw
Config.scala
hosted with ❤ by GitHub

The Service:

package services
import com.example.driver.RedisClient
import com.google.inject.Inject
import com.google.inject.name.Named
class MyRedisService @Inject()(@Named("myDbOne") redisClientOne: RedisClient, @Named("myDbTwo") redisClientTwo: RedisClient) {
def doSomething = {
redisClientOne.doSomething
redisClientTwo.doSomething
}
}

view raw
MyRedisService.scala
hosted with ❤ by GitHub

In order to link everything together and inform Guice of the new Config Module, it’s necessary to add:

play.modules.enabled += "config.Config"

in the configuration.

Full example and app available in: https://github.com/nemo83/play-scala-example

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: