Skip to content

Instantly share code, notes, and snippets.

@tlync
Last active December 28, 2015 20:49
Show Gist options
  • Save tlync/7560473 to your computer and use it in GitHub Desktop.
Save tlync/7560473 to your computer and use it in GitHub Desktop.
Isolate domain models from transaction management. version 2
// dummy session classes for sample codes
final class AnormSession {
def anormMethod = {
println("anorm")
}
def start = {}
def commit = {}
}
final class SlickSession {
def slickMethod = {
println("slick")
}
def start = {}
def commit = {}
}
// domain layer
trait Entity
trait Repo
case class Context[T](session: T)
case class User(id: Int, name: String) extends Entity
trait UserRepo[T] extends Repo {
def find(id: Int)(implicit ctx: Context[T]): User
def store(name: String)(implicit ctx: Context[T]): User
}
// infra layer for persistence
class SlickUserRepo extends UserRepo[SlickSession] {
def find(id: Int)(implicit ctx: Context[SlickSession]): User = {
ctx.session.slickMethod //
User(2, "slick")
}
def store(name: String)(implicit ctx: Context[SlickSession]): User = {
ctx.session.slickMethod
User(2, name)
}
}
class AnormUserRepo extends UserRepo[AnormSession] {
def find(id: Int)(implicit ctx: Context[AnormSession]): User = {
ctx.session.anormMethod
User(2, "slick")
}
def store(name: String)(implicit ctx: Context[AnormSession]): User = {
ctx.session.anormMethod
User(2, name)
}
}
// app layer
object App {
def doSomethingWithSlick() = {
val session = new SlickSession
implicit val context = Context(session)
val repo = new SlickUserRepo
repo.find(1)
}
def doSomethingWithAnorm() = {
val session = new AnormSession
implicit val context = Context(session)
val repo = new AnormUserRepo
repo.find(2)
}
// compile error
def doSomethingButError() = {
case class HogeSession()
val session = new HogeSession
implicit val context = Context(session)
val repo = new SlickUserRepo
repo.find(3)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment