Skip to content

Instantly share code, notes, and snippets.

@upeter
Created March 22, 2011 19:07
Show Gist options
  • Save upeter/881826 to your computer and use it in GitHub Desktop.
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)
}
}
}
@p3t0r
Copy link

p3t0r commented Mar 22, 2011

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): T

    def 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: AccountService

    class 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
    }

@TizianoPerrucci
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment