Thursday, 15 September 2011

Events in Scala -



Events in Scala -

i have categoryrepository class implements several methods such saves category database. have object product contains list of categories. want trigger event product object hear to, , update product new info of category.

in c# know can utilize delegates don't know if can in scala.

i don't want categoryrepository class know class product won't phone call method in product update through categoryrepository.

my categoryrepository class:

trait categoryrepositorycomponentimpl extends categoryrepositorycomponent { val categoryrepository = new categoryrepositoryimpl class categoryrepositoryimpl extends categoryrepository { val dbrepository = categorydbrepository def updateattribute(id:string, request:updatecategoryitem): string = { val cat = dbrepository.get(id) cat.update(request) dbrepository.save(cat) } } }

the product repository looks same category's repository. want add together line after dbrepository.save(cat) trigger event phone call updateproduct() function within productrepository.

please give implementation example. thanks.

a (not so) basic implementation update channel based on events.

i took care generalize bare bone, give hint future evolution , code reuse.

base infrastructure

we introduce updates channel

//listens updates a's , notifies interested listeners class updatechannel[a] { //simplified register var listenmap: map[a, listening[a]] = map() //update phone call def apply(a: a): unit = listenmap.get(a).foreach(_.event(a)) //update phone call def registerfor(a: value, listen: listening[a]) = listenmap += (a, listen) }

and generic listener interested in corrisponding updates

//listens changes type trait listening[a] { def event(upd: a): unit } application

now adapt repo component inject channel

trait categoryrepositorycomponentimpl extends categoryrepositorycomponent { val categoryrepository = new categoryrepositoryimpl /************** new code here ************** * define channel send category updates *******************************************/ def updatechannel: updatechannel[category] class categoryrepositoryimpl extends categoryrepository { val dbrepository = categorydbrepository def updateattribute(id:string, request:updatecategoryitem): string = { val cat = dbrepository.get(id) cat.update(request) dbrepository.save(cat) //send update channel updatechannel(cat) //***************** << , here } } }

we need enable product event listening

//product must listening category updates class product(val category: category) extends listening[category] { def event(cat: category) = ??? //strut stuff here ...business stuff here }

finally, here set ingredients together

//put pieces def wireup() = { //the channel val catchan: updatechannel[category] = new updatechannel[category] //the repository component wired channel val catrep = new categoryrepositorycomponentimpl { val updatechannel = catchan } //a nice cat val mycat: category = ??? //a nice prod nice cat val p: product = new product(mycat) //prod wants know happens cat catchan.registerfor(mycat, p) } remarks

we can create product independent of whole framework using refinement types

val product = new product(mycat) listening[category] { def event(cat: category) = ??? //strut stuff here }

a different solution avoiding wirings , register list of update closures in repositorycomponent

trait categoryrepositorycomponentimpl extends categoryrepositorycomponent { val categoryrepository = new categoryrepositoryimpl //public listeners, should encapsulated var categoryupdates: seq[category => unit] [...] def updateattribute(id:string, request:updatecategoryitem): string = { val cat = dbrepository.get(id) cat.update(request) dbrepository.save(cat) //send update channel categoryupdates.foreach(_.apply(cat)) } }

}

and product needs add together own update function

catrep.categoryupdates +:= (cat) => p.event(cat)

scala events

No comments:

Post a Comment