Can we use Google Guice DI with a Scala Object instead of a Scala class in Play 2.4 with scala
Asked Answered
T

1

3

Our application is built on Play 2.4 with Scala 2.11 and Akka. Cache is used heavily in our application.We use Play's default EhCache for caching.

We currently use the Cache object(play.api.cache.Cache) for Caching

import play.api.Play.current
import play.api.cache.Cache

object SampleDAO extends TableQuery(new SampleTable(_)) with SQLWrapper {
  def get(id: String) : Future[Sample] = {
    val cacheKey = // our code to generate a unique cache key
    Cache.getOrElse[Future[[Sample]](cacheKey) {
      db.run(this.filter(_.id === id).result.headOption)
    }
  }
}

Now with Play 2.4 we plan to make use of the inbuilt Google Guice DI support. Below is a sample example provided by the Play 2.4 docs

import play.api.cache._
import play.api.mvc._
import javax.inject.Inject

class Application @Inject() (cache: CacheApi) extends Controller {

}

The above example inserts dependency into a Scala class constructor. But in our code SampleDAO is a Scala object but not class .

So now Is it possible to implement Google Guice DI with A scala object instead of a scala class ?

Tumor answered 28/6, 2015 at 13:47 Comment(0)
P
2

No, it is not possible to inject objects in guice. Make your SampleDAO a class instead, where you inject CacheApi. Then inject your new DAO class in your controllers. You can additionally annotate SampleDAO with @Singleton. This will ensure SampleDAO will be instantiated only once. The whole thing would look something like this:

DAO

@Singleton
class SampleDAO @Inject()(cache: CacheApi) extends TableQuery(new SampleTable(_)) with SQLWrapper {
  // db and cache stuff
}

Controller

class Application @Inject()(sampleDAO: SampleDAO) extends Controller {
  // controller stuff
}
Poundage answered 28/6, 2015 at 16:24 Comment(5)
Don't you need to bind the the DAO and its Implementation as well? Just in case someone is wondering as well!Inscrutable
@GeorgeNikolaides If separating interface and implementation, then yes. For reasons of simplicity there is no separate interface in the example above. That's why the class (implementation) is injected directly.Poundage
the answer in the below link suggests it is possible to inject dependencies in a Scala object.. any idea about this? #13792315Reciprocity
@mig-foxbat this seems to be rather hacky to me. Assigning null to a val variable is bad practice an in the context of Scala also useless. You must not reassign val in Scala. In the example val s will be reassigned by Guice using reflection. This is like you were reassigning a final variable in Java. A don't do. Anyway, what's your use case? Can't you just use a class instead?Poundage
@Poundage if I have to convert my object to class then I will have to change my other objects that refer my target object to classes and this creates a ripple effect. And I agree with your point of Injecting in object esp val is not a recommended practice and should be used sparingly.Reciprocity

© 2022 - 2024 — McMap. All rights reserved.