Search code examples
javascalaplayframework

Scala - Play framework Creation Exception


I'm trying to add a new controller to my Play framwork but I'm having this exception

CreationException: Unable to create injector, see the following errors:

1) No implementation for service.GithubService was bound.
  while locating service.GithubService
    for the 2nd parameter of controllers.GithubController.<init>(GithubController.scala:12)
  while locating controllers.GithubController
    for the 3rd parameter of router.Routes.<init>(Routes.scala:28)
  at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:139):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$4)

1 error

Here is the HomeController.scala file

package controllers

import play.api._
import play.api.mvc.{BaseController, ControllerComponents}

trait HomeController extends BaseController {
  protected def controllerComponents: ControllerComponents
}

Here is the GithubController.scala file

package controllers

import javax.inject.Inject
import models.GithubRepositoryDTO
import play.api.libs.json.{JsValue, Json}
import play.api.mvc._
import service._

import scala.concurrent.{ExecutionContext, Future}

class GithubController @Inject()(
                                  val controllerComponents: ControllerComponents,
                                  githubService: GithubService
                                )(implicit ec: ExecutionContext) extends HomeController {
  def getStarred(): Action[JsValue] = Action.async(parse.json) { implicit request =>
      githubService.getStarredRepositories()

      Future(Ok("test"))
  }
}

Here is the GithubService.scala file

package service

import models.GithubRepositoryDTO

import scala.concurrent.Future

trait GithubService {
  def getStarredRepositories():Future[Seq[GithubRepositoryDTO]]
}

Here is the GithubServiceImpl.scala file

package service

import javax.inject.Inject
import models.GithubRepositoryDTO
import play.api.libs.json._
import play.api.libs.ws.WSClient

import scala.concurrent.{ExecutionContext, Future}

class GithubServiceImpl @Inject()(
                                  wsClient:WSClient
)(implicit ec: ExecutionContext) extends GithubService {
  def getStarredRepositories(): Future[Seq[GithubRepositoryDTO]] = {
    //some code
  }
}

I've checked if the error comes from the service or controller but still not working, any help or suggestion is welcome. Thanks!


Solution

  • The problem is that GithubServiceImpl has not been registered with the dependency injection container. You can find information on how to do this in the Providing custom bindings section of the documentation.

    The two options are:

    1. Using binding annotations:

      @ImplementedBy(classOf[GithubServiceImpl])
      trait GithubService {
        def getStarredRepositories(): Future[Seq[GithubRepositoryDTO]]
      }
      
    2. Using programmatic binding, in a file called Module.scala in the root of your application:

      import com.google.inject.AbstractModule
      import com.google.inject.name.Names
      
      class Module extends AbstractModule {
        override def configure() = {
          bind(classOf[GithubService])
            .to(classOf[GithubServiceImpl])
        }
      }
      

    Be sure to read the linked documentation for more details on other options and declaring a binding as a singleton.