Dependency injection for bounded generic types via Module.scala

I would appreciate if I could get some help with the following. I am trying to do dependency injection for traits that have bounded parameter types.

trait ImageDAO[T <: ImageSet] {

  def find(id: String): ImageDisplay[T]

  def find(req: ImageSearch): ImageResponse[T]
}

class ProductImageDAO @Inject() (environment: Environment) extends ImageDAO[ProductImageSet] {
...
}

class ProfileImageDAO @Inject() (environment: Environment) extends ImageDAO[ProfileImageSet] {
...
}

case class ProductImageSet(swatchImage: BaseImage, smallImage: BaseImage, mediumImage: BaseImage, largeImage: BaseImage) extends ImageSet

case class ProfileImageSet(smallImage: BaseImage, mediumImage: BaseImage) extends ImageSet

And now, the service trait and its implementation

trait ImageService[A <: ImageSet] {
  def retrieve(id: String): ImageDisplay[A]

  def retrieve(req: ImageSearch): ImageResponse[A]
}

class ImageServiceImpl[T <: ImageSet] @Inject() (imageDAO: ImageDAO[T]) extends ImageService[T] {

  def retrieve(id: String): ImageDisplay[T] = imageDAO.find(id)

  def retrieve(req: ImageSearch): ImageResponse[T] = ???
}

Here is my class MyModule.scala where I want the dependency injection to happen.

class MyModule extends AbstractModule {
    protected def configure() {
        // Dependency injection for ImageDAO for ProductImageDAO and ProfileImageDAO 
        // Dependency injection for ImageService using ImageServiceImpl
    }
}

Hey @noor,

You need to use TypeLiteral. See more details here:

Best.

Thank you @marcospereira. I tried using TypeLiteral as you suggested like below but I am having the following error:

No implementation for dao.ImageDAO<models.ProductImageSet> was bound. while locating dao.ImageDAO<models.ProductImageSet>

Here is what I tried. I’d appreciate your feedback on this.

class MyModule extends AbstractModule {
  protected override def configure() {
    bind(new TypeLiteral[ImageDAO[ProductImageSet]](){}).to(classOf[ProductImageDAO]).asEagerSingleton()
    bind(new TypeLiteral[ImageService[ProfileImageSet]](){}).to(classOf[ImageServiceImpl[ProfileImageSet]]).asEagerSingleton()
    bind(new TypeLiteral[ImageService[ProductImageSet]](){}).to(classOf[ImageServiceImpl[ProductImageSet]]).asEagerSingleton()
   }

}

Hey @noor, is the module enabled in your application.conf?

Hi @marcospereira,

Yes, the module is enabled in my application.conf. would appreciate any help on this.

Thanks

Better if you can create a small reproducer, @noor. It will be easier to see exactly what is happening at least.

Thanks @marcospereira! I managed to fix the issue by having two separate image services impls: one for profile and one for product. I am duplicating code a bit but it works now.