-
-
Save upeter/881826 to your computer and use it in GitHub Desktop.
package snippets | |
object DIExamples { | |
/* | |
* http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html | |
* http://debasishg.blogspot.com/2011/03/pushing-envelope-on-oo-and-functional.html | |
* http://www.assembla.com/wiki/show/liftweb/Dependency_Injection | |
*/ | |
case class Account(id:String, balance:Double) | |
def ??? = throw new Error("not implemented yet") | |
trait Dao[T] { | |
def findById(id:String):T | |
def save(t:T) | |
} | |
trait AccountService { | |
def findAccountById(id:String):Account | |
/** | |
* Check for sufficient balance and perform transfer | |
*/ | |
def transfer(from:Account, to:Account, amount:Double):(Account, Account) | |
} | |
class Client { | |
val accountService:AccountService = ??? | |
def performTransfer() = { | |
val a1 = accountService.findAccountById("1.A") | |
val a2 = accountService.findAccountById("2.B") | |
accountService.transfer(a1, a2, 1000) | |
} | |
} | |
} |
package nl.duse
object DIExamples {
/*
-
http://debasishg.blogspot.com/2011/03/pushing-envelope-on-oo-and-functional.html <=
*/case class Account(id: String, balance: Double)
def ??? = throw new Error("not implemented yet")
trait Dao[T] {
def findById(id: String): Tdef save(t: T)
}trait AccountDaoComponent {
val accountDao: Dao[Account]class AccountDaoImpl extends Dao[Account] {
def findById(refNo: String): Account = {
Map(("1.A", Account("1.A", 110.0)), ("2.B", Account("2.B", 130.0))).get(refNo).getOrElse(Account(refNo, 0))
}
def save(t: Account): Unit = println("writing " + t)
}
}trait AccountService {
def findAccountById(id: String): Account
def transfer(from: Account, to: Account, amount: Double): (Account, Account)
}trait AccountServiceComponent{ this: AccountDaoComponent => // self type annotation that indicates the dependency
val accountService: AccountServiceclass AccountServiceImpl extends AccountService {
def findAccountById(refNo: String) = accountDao.findById(refNo)
def transfer(from: Account, to: Account, amount: Double) = (from.copy(balance = from.balance - amount), to.copy(balance = to.balance + amount))
}
}object AccountServiceAssembly extends AccountDaoComponent with AccountServiceComponent {
val accountDao = new AccountDaoImpl // impl
val accountService = new AccountServiceImpl // impl
}class Client {
import AccountServiceAssembly._def performTransfer() = {
val a1 = accountService.findAccountById("1.A")
val a2 = accountService.findAccountById("2.B")println("a1 " + a1) println("a2 " + a2) val (a3, a4) = accountService.transfer(a1, a2, 10) println("a1 " + a3) println("a2 " + a4)
}
}def main(args:Array[String]) = new Client().performTransfer
}
Guys, take a look at http://skillsmatter.com/podcast/scala/how-we-mostly-moved-from-java-to-scala
object DIExamples {
/*
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
http://debasishg.blogspot.com/2011/03/pushing-envelope-on-oo-and-functional.html
http://www.assembla.com/wiki/show/liftweb/Dependency_Injection
*/
case class Account(id: String, balance: Double)
def ??? = throw new Error("not implemented yet")
trait Dao[T] {
def findById(id: String): T
def save(t: T)
}
class AccountDao extends Dao[Account] {
def save(t: Account) = println("I'm gonna save " + t)
def findById(id: String) = {
println("finding...." + id)
Account(id, 10000)
}
}
trait AccountService {
def findAccountById(id: String): Account
/**
}
class AccountServiceImpl(env: {val dao: Dao[Account]}) extends AccountService {
def transfer(from: Account, to: Account, amount: Double) = {
val newFrom = from.copy(balance = from.balance - amount)
val newTo = to.copy(balance = to.balance + amount)
env.dao.save(newFrom)
env.dao.save(newTo)
(newFrom, newTo)
}
}
// -----------------------------------------------------------------
class Client(env: {val accountService: AccountService}) {
def performTransfer() = {
val a1 = env.accountService.findAccountById("1.A")
val a2 = env.accountService.findAccountById("2.B")
env.accountService.transfer(a1, a2, 1000)
}
}
object DIContext {
lazy val dao = new AccountDao
lazy val accountService = new AccountServiceImpl(this)
}
def main(args: Array[String]) {
new Client(DIContext).performTransfer
}
}