Making Guice more Scala friendly

Guice might be one of the few libraries that is easier to use in Java than it is in Scala. The main reason for this is the absence of class literals in Scala. Instead of writing Service.class in Scala we write classOf[Service] which is longer and less readable. To illustrate this lets compare two Guice modules, one defined in Java and the other in Scala.

Below we have a small Guice module (copied from the documentation of AbstractModule) defined in Java.

public class MyModule extends AbstractModule {
  protected void configure() {
    bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
    bind(CreditCardPaymentService.class);
    bind(PaymentService.class).to(CreditCardPaymentService.class);
    bindConstant().annotatedWith(Names.named("port")).to(8080);
  }
}

In Scala the above code would be:

class MyModule extends AbstractModule {
   protected def configure() {
     bind(classOf[Service]).to(classOf[ServiceImpl]).in(classOf[Singleton])
     bind(classOf[CreditCardPaymentService])
     bind(classOf[PaymentService]).to(classOf[CreditCardPaymentService])
     bindConstant().annotatedWith(Names.named("port")).to(8080)
   }
 }

As you can see the code is longer and it looses the DSL feel that it has in the Java version. This fact may lead Scala developers away from Guice since defining Guice modules in Scala feels awkward and leaves a lot to be desired.

For this reason I’ve created a small project, called sse-guice, that extends Guice’s internal DSL with methods that make defining Guice modules in Scala more pleasant.

What I’ve done is to extend the binder interfaces of Guice (defined in com.google.inject.binder package) and add a method that takes a Manifest for each method that takes a Class as a parameter. Furthermore I’ve extended the AbstractModule class (the entry point of the Guice internal DSL) and added a bind method that accepts a Manifest and I’ve also overridden all the methods that return a binder interface to return the extended binder interfaces provided by sse-guice.

By utilizing sse-guice the above module can be rewritten as:

class MyModule extends ScalaModule {
  protected def configure() {
    bind[Service].to[ServiceImpl].in[Singleton]
    bind[CreditCardPaymentService]
    bind[PaymentService].to[CreditCardPaymentService]
    bindConstant().annotatedWithName("port").to(8080)
  }
}

As you can see the code now is shorter, easier to read and feels like a proper internal DSL.

Another benefit of using Manifest as a parameter is that we can now avoid creating TypeLiterals when we bind generic types. To bind a generic type in Guice you have to write:

bind(new TypeLiteral[Validator[Registration]] {}).to(classOf[RegistrationVSpec])

but when using sse-guice we can simply write:

bind[Validator[Registration]].to[RegistrationVSpec]

because Manifest also holds any type arguments and sse-guice automatically creates a TypeLiteral when the Manifest contains type arguments.