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 infrastructurewe 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