/** Ċ Ġ* ĠĠĠĠĠ ĠRed in Ġ- ĠDependency Ġinjection Ġbuilt Ġon Ġtop Ġof ĠK ores Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠĠĠ ĠThe ĠMIT ĠLicense Ġ( MIT ) Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠCopyright Ġ( c ) Ġ 2 0 2 1 ĠJon athan xD Ġ< https :// github . com / Jon athan xD / Red in > Ċ Ġ* ĠĠĠĠĠ ĠCopyright Ġ( c ) Ġcontributors Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* ĠĠĠĠĠ Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* ĠĠĠĠĠ Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* ĠĠĠĠĠ Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* ĠĠĠĠĠ Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* ĠĠĠĠĠ Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ċ Ġ* ĠĠĠĠĠ Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠĠĠĠĠ ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠĠĠĠĠ ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠĠĠĠĠ ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠĠĠĠĠ ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠĠĠĠĠ ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN Ċ Ġ* ĠĠĠĠĠ ĠTHE ĠSOFTWARE . Ċ Ġ*/ Ċ package Ġcom . github . jon athan xd . red in . test Ċ Ċ import Ġcom . github . jon athan xd . i utils .` object `. Late Init Ċ import Ġcom . github . jon athan xd . red in .* Ċ import Ġorg . junit . Assert Ċ import Ġorg . junit . Test Ċ Ċ class ĠChild Injection Ġ{ ĊĊĠĠĠ Ġ@ Red in Inject ĊĠĠĠ Ġclass ĠBank ( val Ġaccount Service : ĠAccount Service , Ġval Ġobj : ĠObj ) ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġinject () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinjector Ġ= ĠRed in Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbind < Account Service >(). in Scope ( SINGLE TON ). to Implementation < Map Account Service >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbind < Obj >(). in Scope ( SINGLE TON ). to Provider Ġ{ ĠObj () Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġbank Ġ= Ġinjector [ Bank :: class . java ] ĊĊĠĠĠĠĠĠĠ Ġval Ġobj Ġ= Ġbank . obj ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 1 L , Ġbank . account Service . deposit ( Account (" Red in "), Ġ 1 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 2 L , Ġbank . account Service . deposit ( Account (" Red in "), Ġ 1 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 1 2 L , Ġbank . account Service . deposit ( Account (" Red in "), Ġ 1 0 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 2 L , Ġbank . account Service . withdraw ( Account (" Red in "), Ġ 1 0 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 0 L , Ġbank . account Service . withdraw ( Account (" Red in "), Ġ 2 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 1 0 L , Ġbank . account Service . deposit ( Account (" Red in "), Ġ 1 0 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals (- 1 2 L , Ġbank . account Service . withdraw ( Account (" Red in "), Ġ 1 2 L )) Ġ// ĠNot Ġenough Ġmoney ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 0 L , Ġbank . account Service . withdraw ( Account (" Red in "), Ġ 1 0 L )) Ġ// ĠNot Ġenough Ġmoney ĊĊĠĠĠĠĠĠĠ Ġval Ġchild Ġ= Ġinjector . child Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbind < Account Service >(). in Scope ( SINGLE TON ). to Implementation < Map Account Service Self >() ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġchild . inherit Parent Scoped Bindings Cache () ĊĊĠĠĠĠĠĠĠ Ġval Ġbank 2 Ġ= Ġchild [ Bank :: class . java ] ĊĊĠĠĠĠĠĠĠ ĠAssert . assertTrue ( obj Ġ== Ġbank 2 . obj ) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 1 L , Ġbank 2 . account Service . deposit ( Account (" Red in "), Ġ 1 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 1 L , Ġbank 2 . account Service . deposit ( Account (" Red in "), Ġ 1 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 1 0 L , Ġbank 2 . account Service . deposit ( Account (" Red in "), Ġ 1 0 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals (- 1 0 L , Ġbank 2 . account Service . withdraw ( Account (" Red in "), Ġ 1 0 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals (- 2 L , Ġbank 2 . account Service . withdraw ( Account (" Red in "), Ġ 2 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 1 0 L , Ġbank 2 . account Service . deposit ( Account (" Red in "), Ġ 1 0 L )) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 0 , Ġbank 2 . account Service . withdraw ( Account (" Red in "), Ġ 1 2 L )) Ġ// ĠNot Ġenough Ġmoney ĊĊĠĠĠĠĠĠĠ Ġval Ġbank 3 Ġ= Ġinjector [ Bank :: class . java ] Ġ// ĠBase Ġinjector ĊĠĠĠĠĠĠĠ ĠAssert . assertTrue ( obj Ġ== Ġbank 3 . obj ) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals (- 2 L , Ġbank 3 . account Service . withdraw ( Account (" Red in "), Ġ 2 L )) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠObj ĊĊĠĠĠ Ġclass ĠMap Account Service Ġ: ĠAccount Service Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġmap Ġ= Ġmutable Map Of < Account , ĠLong >() ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġwithdraw ( account : ĠAccount , Ġamount : ĠLong ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( amount Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . deposit ( account , Ġamount ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmoney Ġ= Ġthis . map [ account ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( money Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ- amount ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( money Ġ< Ġamount ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ- amount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . map [ account ] Ġ= Ġmoney Ġ- Ġamount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmoney Ġ- Ġamount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġdeposit ( account : ĠAccount , Ġamount : ĠLong ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( amount Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . withdraw ( account , Ġamount ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmoney Ġ= Ġthis . map . compute If Absent ( account ) Ġ{ Ġ 0 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . map [ account ] Ġ= Ġmoney Ġ+ Ġamount ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmoney Ġ+ Ġamount ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠMap Account Service Self Ġ: ĠAccount Service Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġmap Ġ= Ġmutable Map Of < Account , ĠLong >() ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġwithdraw ( account : ĠAccount , Ġamount : ĠLong ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( amount Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . deposit ( account , Ġamount ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmoney Ġ= Ġthis . map [ account ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( money Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( money Ġ< Ġamount ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . map [ account ] Ġ= Ġmoney Ġ- Ġamount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ- amount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġdeposit ( account : ĠAccount , Ġamount : ĠLong ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( amount Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . withdraw ( account , Ġamount ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmoney Ġ= Ġthis . map . compute If Absent ( account ) Ġ{ Ġ 0 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . map [ account ] Ġ= Ġmoney Ġ+ Ġamount ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġamount ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠAccount Service Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġwithdraw ( account : ĠAccount , Ġamount : ĠLong ): ĠLong ĊĠĠĠĠĠĠĠ Ġfun Ġdeposit ( account : ĠAccount , Ġamount : ĠLong ): ĠLong ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠAccount ( val Ġname : ĠString ) Ċ }