package Ġapp . dok t . app Ċ Ċ import Ġkotlin . reflect . K Class Ċ Ċ /** Ċ Ġ* ĠUser ĠID Ġwhich Ġis Ġe . g . Ġcase - ins ensitive Ġunique Ġtoken . Ċ Ġ*/ Ċ interface ĠUserId Ċ Ċ /** Ċ Ġ* ĠCommand Ġtarget Ġ( named Ġ" To " Ġbecause Ġ" Target Ġis Ġreserved Ġin ĠJVM ") Ċ Ġ*/ Ċ data Ġclass ĠTo < I >( ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCommand er Ġuser ĠID ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġuser : ĠUserId , ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCommand Ġtarget Ġ( aggregate Ġor Ġs aga ) ĠID ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġid : ĠI , ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠVersion Ġwhich Ġcommand Ġtarget Ġaggregate Ġroot Ġmust Ġmatch Ġif Ġexists . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġversion : ĠU Short ? Ġ= Ġnull Ċ ) Ġ{ ĊĠĠĠ Ġval Ġmay Exists Ġget () Ġ= Ġ! new ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠTarget Ġ( aggregate Ġor Ġs aga ) Ġmust Ġbe Ġnew ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġnew Ġget () Ġ= Ġversion Ġ== ĠU Short . MIN _ VALUE Ċ } Ċ Ċ /** Ċ Ġ* ĠConcurrent Ġmodification Ġthrown Ġwhen Ġtarget Ġversion Ġisn 't Ġsame Ġas Ġexpected . Ċ Ġ*/ Ċ class ĠVersion Mismatch ( val Ġid : ĠAny , Ġval Ġactual : ĠVersion , Ġval Ġexpected : ĠVersion ) Ġ: ĠException ( ĊĠĠĠ Ġ" Expecting Ġto Ġmodify Ġ$ expected Ġversion Ġof Ġ$ id , Ġbut Ġthe Ġversion Ġwas Ġ$ actual !" Ċ ) Ċ Ċ class ĠDomain Exception ( val Ġid : ĠAny , Ġcause : ĠException ) Ġ: ĠException ( cause ) Ċ Ċ abstract Ġclass ĠApplication Service < R Ġ: ĠAny , ĠI Ġ: ĠAny , ĠE Ġ: ĠRoot Event >( root Type : ĠK Class < R >) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġrepository Ġ= ĠAggregate Repository . get < R , ĠI , ĠE >( root Type ) ĊĊĠĠĠ Ġprotected Ġsuspend Ġfun Ġ< T > Ġtx ( to : ĠTo < I >, Ġcommand : ĠR . () Ġ-> ĠT ) Ġ= Ġwith ( repository . get ( to . id )) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult : ĠT ĊĠĠĠĠĠĠĠ Ġval Ġevents : ĠList < Event Message < I , ĠE >> ĊĠĠĠĠĠĠĠ Ġmutex . lock () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto . version ?. let Ġ{ Ġif Ġ( version Ġ!= Ġit ) Ġthrow ĠVersion Mismatch ( id , Ġversion , Ġit ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Ġ= Ġto . user ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġroot . command () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevents Ġ= Ġcommit () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠVersion Mismatch ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġexception ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrollback () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠDomain Exception ( id , Ġexception ) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmutex . unlock () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbus . dispatch ( events ) ĊĠĠĠĠĠĠĠ Ġresult ĊĠĠĠ Ġ} Ċ } Ċ