Skip to content

Instantly share code, notes, and snippets.

@tlync
Last active December 28, 2015 23:09
Show Gist options
  • Save tlync/7576585 to your computer and use it in GitHub Desktop.
Save tlync/7576585 to your computer and use it in GitHub Desktop.
ドメイン層を特有のトランザクション管理の概念から独立させる為の Transparent context pattern (適当)
// domain layer
trait Entity
trait Repo
case class Context[T](session: T)
trait TransparentContext[T] {
implicit def c2s(implicit ctx: Context[T]) = ctx.session
implicit def s2c(implicit session: T) = Context(session)
}
case class User(id: Int, name: String) extends Entity {
// ..snip..
}
trait UserRepo[T] extends Repo {
def find(id: Int)(implicit ctx: Context[T]): Option[User]
}
// infra layer (for persistence abstraction)
import scalikejdbc._
import SQLInterpolation._
class ScalikeJdbcUserRepo extends UserRepo[DBSession] with TransparentContext[DBSession] {
private def rsToEntity(rs: WrappedResultSet): User = {
User(rs.int("id"), rs.string("name"))
}
def find(id: Int)(implicit ctx: Context[DBSession]): Option[User] = {
sql"select * from users where $id".map(rsToEntity).single().apply()
}
}
// app layer
object UserController extends Controller {
val someService = new AppService() // TODO: DI
def sampleLocalTx = Action {
val user = someService.doSomethingWithLocalTx()
user match {
case u: Some[User] => Ok(u.get.name)
case _ => NotFound
}
}
def sampleAutoCommit = Action {
val user = someService.doSomethingWithAutoCommit()
user match {
case u: Some[User] => Ok(u.get.name)
case _ => NotFound
}
}
}
class AppService extends TransparentContext[DBSession] {
import scalikejdbc._
def doSomethingWithLocalTx() = {
DB localTx { implicit session =>
val repo = new ScalikeJdbcUserRepo
repo.find(1)
// ...
}
}
def doSomethingWithAutoCommit() = {
DB autoCommit { implicit session =>
val repo = new ScalikeJdbcUserRepo
repo.find(1)
// ...
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment