package Ġcom . example . android . architecture . blueprint s . todo app Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġandroidx . room . Room Ċ import Ġcom . example . android . architecture . blueprint s . todo app . data . source . Default Tasks Repository Ċ import Ġcom . example . android . architecture . blueprint s . todo app . data . source . Tasks DataSource Ċ import Ġcom . example . android . architecture . blueprint s . todo app . data . source . Tasks Repository Ċ import Ġcom . example . android . architecture . blueprint s . todo app . data . source . local . Tasks Local DataSource Ċ import Ġcom . example . android . architecture . blueprint s . todo app . data . source . local . ToDo Database Ċ import Ġcom . example . android . architecture . blueprint s . todo app . data . source . remote . Tasks Remote DataSource Ċ import Ġkotlinx . coroutines . run Blocking Ċ Ċ // object Ġkeyword Ġin ĠKotlin Ġcreates Ġa Ġsingleton Ġclass . ĠIt Ġis Ġused Ġto Ġobtain Ġa Ġdata Ġtype Ġwith Ġa Ġsingle Ġimplementation . Ċ // basic ally , Ġit Ġensures Ġyou Ġthat Ġonly Ġone Ġinstance Ġof Ġthat Ġclass Ġis Ġcreated Ġeven Ġif Ġ 2 Ġthreads Ġtry Ġto Ġcreate Ġit . Ċ // a Ġsingleton Ġclass Ġis Ġa Ġclass Ġthat Ġcan Ġhave Ġonly Ġone Ġobject Ġ( an Ġinstance Ġof Ġthe Ġclass ) Ġat Ġa Ġtime Ċ // the Ġpurpose Ġof Ġthe Ġsingleton Ġclass Ġis Ġto Ġcontrol Ġobject Ġcreation , Ġlimiting Ġthe Ġnumber Ġof Ġobjects Ġto Ġonly Ġone . ĠThe Ġsingleton Ġallows Ġonly Ġone Ġentry Ġpoint Ġto Ġcreate Ġthe Ġnew Ġinstance Ġof Ġthe Ġclass . Ċ object ĠService Locator Ġ{ Ġ// Service Locator Ġclass Ġpurpose Ġis Ġto Ġbe Ġable Ġto Ġconstruct ( create ) Ġand Ġstore Ġa Ġrepository ĊĊĠĠĠ Ġprivate Ġval Ġlock Ġ= ĠAny () ĊĊĠĠĠ Ġprivate Ġvar Ġdatabase : ĠTo Do Database ? Ġ= Ġnull ĊĠĠĠ Ġ@ Volatile Ġ// Annot ate Ġthe Ġrepository Ġwith Ġ@ Volatile Ġbecause Ġit Ġcould Ġbe Ġused Ġand Ġrequested Ġby Ġmultiple Ġthreads ĊĠĠĠ Ġvar Ġtasks Repository : ĠTasks Repository ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ@ Visible ForTesting Ġset Ġ// Visible ForTesting Ġannotation Ġmeans Ġthat Ġthe Ġreason Ġa Ġcertain Ġmethod Ġ( or Ġobject ) Ġis Ġpublic Ġis Ġbecause Ġof Ġtesting , Ġmeans Ġthat Ġit Ġthe Ġnormal Ġmain Ġcode , Ġyou Ġshould Ġnever Ġbe Ġable Ġto Ġcall Ġthis Ġsetter Ġmethod , Ġbut Ġin Ġtest / android Test Ġsource Ġsets Ġyou Ġcan . ĊĊĊĊĠĠĠ Ġ// Right Ġnow Ġthe Ġonly Ġthing Ġyour ĠService Locator Ġneeds Ġto Ġdo Ġis Ġknow Ġhow Ġto Ġreturn Ġa ĠTasks Repository . ĊĠĠĠ Ġ// It 'll Ġreturn Ġa Ġpre - existing ĠDefault Tasks Repository Ġor Ġmake Ġand Ġreturn Ġa Ġnew ĠDefault Tasks Repository Ġif Ġneeded . Ċ Ċ // Either Ġprovides Ġan Ġalready Ġexisting Ġrepository Ġor Ġcreates Ġa Ġnew Ġone . Ċ // This Ġmethod Ġshould Ġbe Ġsynchronized Ġon Ġ" this " Ġto Ġavoid Ġ- in Ġsituations Ġwith Ġmultiple Ġthreads Ġrunning - Ġever Ġaccidentally Ġcreating Ġtwo Ġrepository Ġinstances . ĊĠĠĠ Ġfun Ġprovide Tasks Repository ( context : ĠContext ): ĠTasks Repository Ġ{ Ġ Ġ// this Ġmethod Ġtakes Ġa ĠContext Ġto Ġbe Ġable Ġto Ġset Ġup Ġthe Ġdatabase ĊĠĠĠĠĠĠĠ Ġsynchronized ( this ) Ġ{// make Ġsure Ġ Ġthat Ġthe Ġcreation Ġof Ġthe ĠTasks Repository Ġnever Ġactually Ġhappens Ġtwice Ġvia Ġputting Ġit Ġin Ġa Ġsynchronized Ġblock , Ġthis Ġcould Ġactually Ġhappen Ġif Ġthis Ġclass Ġis Ġgetting Ġac ce sed Ġby Ġmultiple Ġthreads , Ġand Ġit Ġwill , Ġso Ġput Ġthe Ġcode Ġin Ġa Ġsynchronized Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtasks Repository Ġ?: Ġcreate Tasks Repository ( context ) Ġ Ġ// the Ġsyntax Ġhere Ġreads : Ġif Ġtasks Repository Ġis Ġnull , Ġthen Ġcall Ġcreate Tasks Repository () Ġand Ġreturn Ġthe Ġobject Ġthe Ġmethod Ġreturns Ġinstead ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ // Method Ġfor Ġcreating Ġa Ġnew Ġrepository . ĠWill Ġcall Ġcreate Task Local DataSource Ġand Ġcreate Ġa Ġnew ĠTasks Remote DataSource . ĊĠĠĠ Ġprivate Ġfun Ġcreate Tasks Repository ( context : ĠContext ): ĠTasks Repository Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnew Repo Ġ= ĠDefault Tasks Repository ( Tasks Remote DataSource , Ġcreate Task Local DataSource ( context )) ĊĠĠĠĠĠĠĠ Ġtasks Repository Ġ= Ġnew Repo ĊĠĠĠĠĠĠĠ Ġreturn Ġnew Repo ĊĠĠĠ Ġ} Ċ Ċ // Method Ġfor Ġcreating Ġa Ġnew Ġlocal Ġdata Ġsource . ĠWill Ġcall Ġcreate Data Base . ĊĠĠĠ Ġprivate Ġfun Ġcreate Task Local DataSource ( context : ĠContext ): ĠTasks DataSource Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdatabase Ġ= Ġdatabase Ġ?: Ġcreate Data Base ( context ) Ġ// the Ġsyntax Ġhere Ġreads : Ġif Ġdatabase Ġis Ġnull , Ġthen Ġcall Ġcreate Data Base () Ġand Ġreturn Ġthe Ġobject Ġthe Ġmethod Ġreturns Ġinstead ĊĠĠĠĠĠĠĠ Ġreturn ĠTasks Local DataSource ( database . task Dao ()) ĊĠĠĠ Ġ} Ċ Ċ // Method Ġfor Ġcreating Ġa Ġnew Ġdatabase . ĊĠĠĠ Ġprivate Ġfun Ġcreate Data Base ( context : ĠContext ): ĠTo Do Database Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠRoom . database Builder ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . application Context , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTo Do Database :: class . java , Ġ" Tasks . db " ĊĠĠĠĠĠĠĠ Ġ). build () ĊĠĠĠĠĠĠĠ Ġdatabase Ġ= Ġresult ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĊĊĠĠĠ Ġ/* One Ġof Ġthe Ġdown sides Ġof Ġusing Ġa Ġservice Ġlocator Ġis Ġthat Ġit Ġis Ġa Ġshared Ġsingleton . ĊĠĠĠ ĠIn Ġaddition Ġto Ġneeding Ġto Ġreset Ġthe Ġstate Ġof Ġthe Ġrepository Ġin Ġthe Ġservice Ġlocator Ġwhen Ġthe Ġtest Ġfinishes , Ġyou Ġcannot Ġrun Ġtests Ġin Ġparallel . ĊĠĠĠ ĠThis Ġdoesn 't Ġhappen Ġwhen Ġyou Ġuse Ġdependency Ġinjection Ġwhich Ġis Ġone Ġof Ġthe Ġreasons Ġto Ġprefer Ġconstructor Ġdependency Ġinjection Ġwhen Ġyou Ġcan Ġuse Ġit . ĊĠĠĠ ĠWhich Ġis Ġwhy Ġwe 're Ġgoing Ġto Ġcreate Ġa Ġtesting Ġspecific Ġmethod Ġcalled Ġreset Repository Ġwhich Ġclears Ġout Ġthe Ġdatabase Ġand Ġsets Ġboth Ġthe Ġrepository Ġand Ġdatabase Ġback Ġto Ġnull */ ĊĠĠĠ Ġ@ Visible ForTesting Ġ// mark Ġthis ĠVis ible ForTesting Ġbecause Ġyou 'll Ġonly Ġever Ġwant Ġto Ġreset Ġthe Ġrepository Ġfrom Ġwithin Ġtests ĊĠĠĠ Ġfun Ġreset Repository () Ġ{ ĊĠĠĠĠĠĠĠ Ġsynchronized ( lock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTasks Remote DataSource . delete All Tasks () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠClear Ġall Ġdata Ġto Ġavoid Ġtest Ġpoll ution . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase ?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclear All Tables () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclose () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtasks Repository Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ }