Reputation: 11289
I am using Play with Scala and I am trying to create a singleton, and i want to inject it from its trait and not directly.
for example:
@ImplementedBy(classOf[S3RepositoryImpl])
trait S3Repository {
}
@Singleton
class S3RepositoryImpl extends S3Repository {
}
But this fails with error:
trait Singleton is abstract; cannot be instantiated
I have tried several combinations and they all produce the same.
I come from Spring background and its very natural there? am i missing something about how Guice handles this type of Injection?
Thanks.
Upvotes: 11
Views: 6921
Reputation: 997
Import both Inject and Singleton.
import javax.inject.{Inject, Singleton}
Refrain from using:
import com.google.inject.{Inject, Singleton}
as play framework requires the javax import
Upvotes: 2
Reputation: 238
Use below import, instead of import javax.inject.Singleton
import com.google.inject.{Inject, Singleton}
Upvotes: 4
Reputation: 4392
As pointed out by @Tavian-Barnes, the solution is to ensure you have the following import:
import javax.inject.Singleton
Upvotes: 41
Reputation: 3921
I have here a "complete" working example, just hope that I'm not stating the obvious...
package controllers
import play.api._
import play.api.mvc._
import com.google.inject._
class Application @Inject() (s3: S3Repository) extends Controller {
def index = Action {
println(s3.get)
Ok
}
}
@ImplementedBy(classOf[S3RepositoryImpl])
trait S3Repository {
def get: String
}
@Singleton
class S3RepositoryImpl extends S3Repository {
def get: String = "bla"
}
Whenever you mark a class' constructor with @Inject
the Guice will manage the injection of the instance itself. So, if you marked your class as @Singleton
, Guice will create and will always give you just that one instance. Nobody can stop you from manually instantiating a class in your code... You can explore it in detail at Play.
Upvotes: 6