// ĠCopyright Ġ( c ) Ġ 2 0 1 9 ĠAle ks and r ĠM ink in Ġ( sp hc @ yandex . ru ) Ċ // Ċ // Ġ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 . Ċ @ file : Suppress (" unchecked _ cast ") Ċ package Ġcom . min cor . k od ire f lect Ċ import Ġcom . min cor . k od ire f lect . ext .* Ċ import Ġkotlin . reflect . K Function ĊĊ Ċ /** Ċ Ġ* ĠMain ĠSingleton Ġobject Ġfor Ġmanipulate Ġinstances Ċ Ġ*/ Ċ object ĠK odi Reflect Ġ: ĠI Mapper < Any >, ĠIK odi Reflect Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInstance Ġmap Ġfor Ġholding Ġany Ġtype Ġof Ġdependencies ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġval Ġinstance Storage Ġ= Ġmutable Map Of < String , ĠAny >() Ċ } Ċ Ċ /** Ċ Ġ* ĠHelper Ġinterface Ġfor Ġbind Ġgeneric Ġinstances Ġwith Ġname Ċ Ġ*/ Ċ interface ĠI Mapper < T Ġ: ĠAny > Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMain Ġentities ( instances ) Ġholder Ġmap ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġinstance Storage : ĠMutable Map < String , ĠT > Ċ } Ċ Ċ /** Ċ Ġ* ĠSimple Ġimplementing Ġinterface Ġfor Ġdi Ġfunctionality Ċ Ġ*/ Ċ interface ĠIK odi Reflect Ċ Ċ /** Ċ Ġ* ĠRemove Ġall Ġinstances Ġfrom Ġstore Ċ Ġ*/ Ċ fun ĠIK odi Reflect . removeAll () Ġ{ ĊĠĠĠ Ġ( K odi Reflect Ġas ĠI Mapper < Any >). removeAll () Ċ } Ċ Ċ /** Ċ Ġ* ĠInitialize ĠK O DI Reflect Ġdependencies Ċ Ġ*/ Ċ inline Ġfun Ġinit KO DI Reflect ( block : ĠIK odi Reflect . () Ġ-> ĠUnit ): ĠIK odi Reflect Ġ{ ĊĠĠĠ ĠK odi Reflect . block () ĊĠĠĠ Ġreturn ĠK odi Reflect Ċ } Ċ Ċ /** Ċ Ġ* Ġ ĠRemove Ġall Ġinstances Ġfrom Ġmap Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠI Mapper < T >. removeAll () Ġ{ ĊĠĠĠ Ġinstance Storage . forEach Ġ{ Ġ(_, Ġinstance ) Ġ-> ĊĠĠĠĠĠĠĠ Ġ( instance Ġas ? ĠProvider Holder < T ?> )?. clear () ĊĠĠĠ Ġ} ĊĠĠĠ Ġinstance Storage . clear () Ċ } Ċ Ċ /** Ċ Ġ* ĠRemove Ġinstance Ġfrom Ġmap Ġby Ġgiven Ġkey Ċ Ġ* Ċ Ġ* Ġ@ param Ġkey Ċ Ġ* ĠKey Ġto Ġremove Ġinstance Ċ Ġ*/ Ċ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠK odi Reflect . remove Instance ( key : ĠString ) Ġ{ ĊĠĠĠ Ġif Ġ( has Instance ( key )) Ġ( this . instance Storage . remove ( key ) Ġas ? ĠProvider Holder < T ?> )?. clear () Ċ } ĊĊ Ċ /** Ċ Ġ* ĠBind ĠKey Ġto ĠValue Ġtype Ġand Ġreturn Ġan Ġinstance Ġof ĠValue Ċ Ġ* Ċ Ġ* Ġ@ param Ġtag Ġ- Ġcurrent Ġconstant Ġtag Ċ Ġ* Ġ@ param Ġvalue Ġ- Ġconstant Ġvalue Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . constant ( ĊĠĠĠĠĠĠĠ Ġtag : ĠString , ĊĠĠĠĠĠĠĠ Ġvalue : ĠT Ġ= ĠT :: class . create Instance () Ċ ): ĠT Ġ= ĠK odi Reflect . create Or Get ( tag ) Ġ{ Ġvalue Ġ} Ġas ĠT Ċ Ċ /** Ċ Ġ* ĠBind ĠKey Ġto ĠValue Ġtype Ġand Ġreturn Ġan Ġinstance Ġof ĠValue Ċ Ġ* Ċ Ġ* Ġ@ param Ġparams Ġ- Ġ[] Ġof Ġinput Ġparams Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠK Ġ: ĠAny , Ġre ified ĠV Ġ: ĠAny > ĠIK odi Reflect . bind ( var arg Ġparams : ĠAny ): ĠV Ġ{ ĊĠĠĠ Ġreturn ĠK odi Reflect . create Or Get ( K :: class . className ()) Ġ{ ĊĠĠĠĠĠĠĠ ĠV :: class . create Instance ( params . toList ()) ĊĠĠĠ Ġ}. inject In Constructor ( params . toList ()) Ġas ĠV Ċ } Ċ Ċ /** Ċ Ġ* ĠGET Ġa Ġsingle Ġobject Ġreference , Ġit Ġgar anted Ġthat Ġyou Ġhave Ġonly Ġone Ġinstance Ġof Ġan Ġgiven Ġgeneric Ġclass Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . single ( var arg Ġparams : ĠAny ): ĠT Ġ= Ġthis . single With List ( params . toList ()) Ċ Ċ /** Ċ Ġ* ĠIt 's Ġprovide Ġa Ġlambda Ġto Ġcreate Ġsingle Ġsaved Ġinstance Ċ Ġ* Ċ Ġ* Ġ@ param Ġparams Ġ- Ġ[] Ġof Ġinput Ġparams Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . single Provider ( cross inline Ġblock : Ġ() Ġ-> ĠT ): ĠT Ġ= ĠK odi Reflect . create Or Get ( T :: class . className ()) Ġ{ ĊĠĠĠ Ġblock () Ċ } Ġas ĠT Ċ Ċ /** Ċ Ġ* ĠGET Ġa Ġsingle Ġobject Ġreference , Ġit Ġgar anted Ġthat Ġyou Ġhave Ġonly Ġone Ġinstance Ġof Ġan Ġgiven Ġgeneric Ġclass Ċ Ġ* Ċ Ġ* Ġ@ param Ġparams Ġ- Ġ[] Ġof Ġinput Ġparams Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . single With List ( params : ĠList < Any >? Ġ= Ġnull ): ĠT Ġ= ĠK odi Reflect . create Or Get ( T :: class . className ()) Ġ{ ĊĠĠĠ ĠT :: class . create Instance ( params ) Ċ }. inject In Constructor ( params ) Ġas ĠT Ċ Ċ /** Ċ Ġ* ĠCreate Ġan Ġinstance Ġof Ġa Ġgiven Ġgeneric Ġclass Ġwithout Ġsaving Ġto Ġinstance Storage Ċ Ġ* Ċ Ġ* Ġ@ param Ġparams Ġ- Ġ[] Ġof Ġinput Ġparams Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . instance ( var arg Ġparams : ĠAny ): ĠT Ġ= ĠT :: class . create Instance ( params . asList ()) Ċ Ċ /** Ċ Ġ* ĠCreate Ġan Ġinstance Ġof Ġa Ġgiven Ġgeneric Ġclass Ġand Ġsave Ġit Ġto Ġinstance Storage Ġby Ġtag Ġname Ċ Ġ* Ġ@ param Ġtag Ċ Ġ* ĠTag Ġname Ġfor Ġinstance Ġto Ġsave Ċ Ġ* Ċ Ġ* Ġ@ param Ġparams Ċ Ġ* ĠConstructor Ġparams Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . instance By Tag ( tag : ĠString , Ġvar arg Ġparams : ĠAny ): ĠT Ġ= ĠK odi Reflect . create Or Get ( tag ) Ġ{ ĊĠĠĠ ĠT :: class . create Instance ( params . asList ()) Ċ }. inject In Constructor ( params . asList ()) Ġas ĠT Ċ Ċ /** Ċ Ġ* ĠG ives Ġto Ġus Ġan Ġinstance Ġof ĠProvider Holder Ġclass Ġthat Ġstore Ġa Ġreference Ġto Ġfunction Ġand Ġparameters Ġfor Ġfuture Ġcalls Ċ Ġ* Ġ@ param Ġtag Ċ Ġ* ĠTag Ġname Ġfor Ġinstance Ġto Ġsave Ċ Ġ* Ċ Ġ* Ġ@ param Ġfunction Ċ Ġ* ĠThis Ġis Ġa Ġfunction Ġfor Ġcall Ġlater . ĠIf Ġthere Ġis Ġno Ġtag Ġor Ġfunction Ġdoes Ġnot Ġexist Ġin Ġcurrent Ġinstance Store Ġit 's Ġthrow Ġan ĠError Ċ Ġ* Ċ Ġ* Ġ@ param Ġparams Ċ Ġ* Ġfunction Ġparams Ġas ĠlistOf < Any >( ...) Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . provider ( tag : ĠString Ġ= Ġ"", Ġfunction : ĠK Function < T ?> ? Ġ= Ġnull , Ġparams : ĠList < Any >? Ġ= Ġnull ): ĠProvider Holder < T ?> Ġ{ ĊĠĠĠ Ġif Ġ(! K odi Reflect . has Instance ( tag ) Ġ&& Ġfunction Ġ== Ġnull ) Ġthrow ĠExceptions . Provider Exception ( tag ) ĊĠĠĠ Ġval Ġval map Ġ= Ġparams ?. to Val Map ( function ?. parameters ) ĊĠĠĠ Ġval Ġkey Ġ= Ġif Ġ( tag . isEmpty ()) Ġfunction ?. name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠExceptions . Provider Exception ( tag ) Ġelse Ġtag ĊĠĠĠ Ġreturn ĠK odi Reflect . create Or Get ( key ) Ġ{ ĊĠĠĠĠĠĠĠ ĠProvider Holder ( function , Ġval map ) ĊĠĠĠ Ġ} Ġas ĠProvider Holder < T ?> Ċ } Ċ Ċ /** Ċ Ġ* Ġimmediately Ġcalls Ġthe Ġfunction Ġwith Ġgiven Ġparams . ĠIf Ġprovider Ġdoesnt Ġexist Ġits Ġcreate Ġone Ġand Ġmake Ġcall Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . provider Call ( tag : ĠString Ġ= Ġ"", Ġfunction : ĠK Function < T >? Ġ= Ġnull , Ġvar arg Ġparams : ĠAny ): ĠT ? Ġ{ ĊĠĠĠ Ġreturn Ġprovider ( tag , Ġfunction ). call ( params . asList ()) Ċ } Ċ Ċ /** Ċ Ġ* Ġimmediately Ġcalls Ġthe Ġfunction Ġwith Ġgiven Ġparams . ĠIf Ġprovider Ġdoesnt Ġexist Ġits Ġcreate Ġone Ġand Ġmake Ġcall Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . provider Call By Tag ( tag : ĠString Ġ= Ġ"", Ġvar arg Ġparams : ĠAny ): ĠT ? Ġ{ ĊĠĠĠ Ġreturn Ġprovider < T >( tag ). call ( params . asList ()) Ċ } ĊĊ Ċ /** Ċ Ġ* ĠCheck Ġif Ġan Ġinstance Ġfrom Ġstore Ġby Ġgiven Ġtag Ġor Ġgeneric Ġclass Ġexist Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . has ( tag : ĠString ? Ġ= Ġnull ) Ġ{ ĊĠĠĠ ĠK odi Reflect . has Instance ( tag Ġ?: ĠT :: class . className ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠRemove Ġan Ġinstance Ġfrom Ġstore Ġby Ġgiven Ġtag Ġor Ġgeneric Ġclass Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . remove ( tag : ĠString ? Ġ= Ġnull ) Ġ{ ĊĠĠĠ ĠK odi Reflect . remove Instance < T >( tag Ġ?: ĠT :: class . className ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠLazy Ġimplementation Ġof Ġsingle < T >() Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . single Lazy ( var arg Ġparams : ĠAny ): ĠLazy < T > Ġ= Ġkotlin . lazy Ġ{ ĊĠĠĠ Ġthis . single With List < T >( params . asList ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠLazy Ġimplementation Ġof Ġinstance < T >() Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . instance Lazy ( var arg Ġparams : ĠAny ): ĠLazy < T > Ġ= Ġkotlin . lazy Ġ{ ĊĠĠĠ ĠT :: class . create Instance ( params . asList ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠLazy Ġimplementation Ġof Ġinstance By Tag < T >() Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . instance Lazy By Tag ( tag : ĠString , Ġvar arg Ġparams : ĠAny ): ĠLazy < T > Ġ= Ġkotlin . lazy Ġ{ ĊĠĠĠ Ġthis . instance By Tag < T >( tag , Ġparams . asList ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠLazy Ġimplementation Ġof Ġprovider < T >() Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . provider Lazy ( tag : ĠString Ġ= Ġ"", Ġfunction : ĠK Function < T ?> ? Ġ= Ġnull , Ġvar arg Ġparams : ĠAny ): ĠLazy < Provider Holder < T ? >> Ġ= Ġkotlin . lazy Ġ{ ĊĠĠĠ Ġthis . provider ( tag , Ġfunction , Ġparams . asList ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠMutable ĠLazy Ġimplementation Ġof Ġsingle < T >() Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . single Mutable Lazy ( var arg Ġparams : ĠAny ): ĠMutable Lazy < T ?> Ġ= ĠMutable Lazy Ġ{ ĊĠĠĠ Ġthis . single With List < T >( params . asList ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠMutable Lazy Ġimplementation Ġof Ġinstance < T >() Ċ Ġ* Ċ Ġ* Ġ@ param Ġparams Ġ- Ġvar arg Ġfor Ġinject Ġinto Ġcreated Ġinstance Ġconstructor Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . instance Mutable Lazy ( var arg Ġparams : ĠAny ): ĠMutable Lazy < T ?> Ġ= ĠMutable Lazy Ġ{ ĊĠĠĠ ĠT :: class . create Instance ( params . asList ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠMutable Lazy Ġimplementation Ġof Ġprovider < T >() Ċ Ġ* Ċ Ġ* Ġ@ param Ġtag Ġ- Ġtag Ġfor Ġmapping Ċ Ġ* Ġ@ param Ġfunction Ġ- Ġfunction Ġfor Ġinitialization Ċ Ġ* Ġ@ param Ġparams Ġ- Ġadditional Ġparameters Ġto Ġinject Ċ Ġ*/ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠAny > ĠIK odi Reflect . provider Mutable Lazy ( ĊĠĠĠĠĠĠĠ Ġtag : ĠString Ġ= Ġ"", ĊĠĠĠĠĠĠĠ Ġfunction : ĠK Function < T >? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġvar arg Ġparams : ĠAny Ċ ): ĠMutable Lazy < Provider Holder < T ? >> Ġ= ĠMutable Lazy Ġ{ ĊĠĠĠ Ġthis . provider ( tag , Ġfunction , Ġparams . asList ()) Ċ }