0
votes

I'm using the cake pattern for injecting dependencies between components in a play 2.2.1 application. Application is composed of play controllers and we use a custom ActionBuilder to open our DB session. We currently pass that DB session all the way back to our model layer through the controller and DAO layers as implicit argument. (ActionBuilder -> Controller -> DAO -> Slick Model)

I use play-slick for slick integration and try to use a DAO approach to encapsulate access to our slick models. Our DAOs have several function definitions like findById(id: Int)(implicit s: Session): Option[Entity]. I would like to avoid that implicit session parameter in every single function definition by injecting a DBSession-retrieving component. This component would be invoked inside the DAO function blocks everytime to retrieve the current request db session.

Coming from the Java and Spring world, I don't know exactly how to achieve that given that I probably can't rely on any ThreadLocal scoped proxy.

Any idea how I would be able to achieve that? Is this a good or bad idea?

2

2 Answers

1
votes

You can put all of your methods into a class, that takes an implicit session as an argument and then you always first instantiate the class and then call a method. Example here: http://slick.typesafe.com/doc/2.0.2/connection.html#passing-sessions-around

0
votes

If you can retrieve the DB Session as a function of the Request, then you could provide an implicit conversion to convert Request => DBSession.

Like this:

implicit def request2DBSession(request: Request[T]): DBSession = ???

Inside of which you can perform your DBSession retrieval.

EDIT:

Better yet you could use action composition to inject a Session with each request:

trait BaseController extends Controller {
  def DBAction(f: (request[_]) => DBSession => Result) = {
    Action { request =>
      val dbSession = ??? // Lookup DBSession
      f(request)(dbSession)
    }
  }  
}

object Controller extends BaseController {
  def lookupUser = DBAction { implicit request => implicit dbSession =>
    ??? // DBSession in Implicit Scope (free to use slick calls)
  }
}

This would be a little cleaner in my opinion.