Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - Injecting Generic type using guice when dependency class is also using same generic type

I want to inject dependency with Generic type using Guice. Find below example in scala which replicate the issue.

ProductModel.scala

trait BaseProduct  

case class Product() extends BaseProduct 

CartService.scala

class CartService[A <: BaseProduct] @Inject()(productService : ProductService[A]) {
 def getCartItems = productService.getProduct
}

ProductService.scala

class ProductService[A]{
 def getProduct = println("ProductService")
}

Main.scala

object Main extends App {

  val injector = Guice.createInjector(new ShoppingModule)
  val cartService = injector.getInstance(classOf[CartService[Product]])
  cartService.getCartItems
}

class ShoppingModule extends AbstractModule with ScalaModule {
  override def configure(): Unit = {
    bind[BaseProduct].to(scalaguice.typeLiteral[Product])
  }
}

while running this Main.scala app getting below error.

service.ProductService<A> cannot be used as a key; It is not fully specified.

I have tried binding using codingwell library. But it doesn't help to identify ProductService Type.

like image 690
Ripal Patel Avatar asked Jun 13 '18 06:06

Ripal Patel


1 Answers

When you create instance of cartService at that time use typeLiteral to create instance like

val cartService = injector.getInstance(Key.get(scalaguice.typeLiteral[CartService[Product]])

if you create instance like above you don't need to create module. Create injector using default Module (i.e. useful if you have any other bindings in default Module.scala at application level)

val appBuilder = new GuiceApplicationBuilder()
val injector = Guice.createInjector(appBuilder.applicationModule())

and if you don't have any module you can skip passing module as argument and create injector without passing any module as well like

val injector = Guice.createInjector()
like image 121
Nikunj Undhad Avatar answered Oct 18 '22 19:10

Nikunj Undhad