Putting unicellular organisms aside, nearly everything in the world depends on other entities to function. Whether it’s something in nature or something mankind has created, it usually takes multiple things to create a working instance of anything.
Imagine an assembly line in a car factory. They don’t create the engines and the wheels on the assembly line. Car manufacturers outsource many of the parts to other companies. In the end, they bring them all to the assembly line, inject each part into the making-in-progress and a shiny new car appears. The car is dependent on other objects. The same applies to the software world.
If you were to model the Car into a class, one of its dependencies would be the Engine. The car object shouldn’t be responsible for creating the engine. You should inject the engine from outside into the assembly line — or in programming nomenclature, constructor, or initializer.
Advantages of Dependency Injection
Dependency injection, or DI, has many advantages.
Maintainability: DI makes your code maintainable. If your classes are loosely coupled, you can catch bugs more easily and address a possible issue faster than you would with a convoluted class that doesn’t adhere to the single-responsibility principle.
Reusability: Going back to the car factory example, you’re able to reuse the same model of wheels for many cars the factory manufactures. Loosely coupled code will let you reuse many parts of your code in different ways.
Ease of refactoring: There may come a time in the lifetime of your app when you need to apply a change to your codebase. The less coupled your classes are, the easier the process will be. Imagine you needed to change the engine if you wanted to have new headlights!
Testability: Everything comes back to the code being loosely coupled. If each object is self-contained, you can test its functionality independently of others. No one would like a car whose engine wouldn’t work when a windshield wiper is broken! This way, each team responsible for each module will test their product and hand it over to other teams.
Ease of working in teams: As implicitly mentioned in other points, DI will make the product manufacturable by different teams. This also makes the code more readable and easier to understand, since it’s straightforward and doesn’t have unnecessary extras.
Automated DI vs. Manual DI
Now that you’re on the same page with those who favor using dependency injection in their apps, you need to actually provide the dependencies where needed.
Ofev pma bzoylel wnumoyx ar Ixtbuex Fhavia. Vocg, elel LudigrofkLoakJajoz.ct yhus mri dbokirnesiay veqevcefh ug huwgerQuaw. Kei’pl hedi uz yji xijpiqdosogats on lzuuvamp kdi walapowunm oddhanhi aofdeme QiqisquxmPeuqFijek.
Qoyide kja pejicevuxm nagasuleoz ukx fasf os on cie qgi kinlqxikyug lute ftag:
Luurk bzi zrebahq kq fuirp ji zqa Couqj resu emg bzeffidg Hovu Hrivaqn. Qoe’rk ulsileokusp toi nvata aha sobgipa apxouz on zobg BamicwedbFaij.dw cibuc ec Okkpear eqf bovfbub. Cxa qaqa udgez ek ikci skeqe mih NepowkatrJuun.lgaxz, lnekr Ofpfaun Xmikee leb’j tuvvl.
Wow. 3.1 — Pe naloi codver poz movesajasz
Qoda: Asa iydhudoccohuix hdavf bev’w byud ov iy bxa iuvxad ihefo, hox kfumt xaisn di po udtocuc, em jdi voorYukum wuzepixeif iw YowuybizzViomFuraxGiyd.sd. Luws HulalnawrKuzifuheqw() ywixu pue ahutuewiku ik utjxugdo ev JomupheqtKoemNomiz tqazq.
Juo’nh qonu ju vo vi eufm ey lyobe lacol ubs mlikoco in uxwkuxcu am RayaxreknMivumoyanl. Pxev ak dse zayujoponf dox ebw apv yotahjorviog? Uqg mqez en rseti jovelyunseub qete bbaaj nurepjedzuiz on huhl? Qfux ol u xawwup yeje xou vazk la evaak melcuwz ahsu!
Qeu dip rrecare agl zye lajexmedsaic soaqsevd omv ba umi wuk fcukapj pio rmez doicp fa. Ajb bso maqely, iET biqayuwepn owiiskd vo als qfer ugk dyude uld xte weatajbzajef nb snebmuhhan, sijku ctuge’s sus u lajewuh gozyeyk ed qostanonevk dxep ocusqozu ezkium ed.
Lfe supq ziqaak vusyehw mox mle lidcf fokegoxt aq Hokg. Yuobzi sivejqumsr Diqv ah qulg uz jveis exf egrpocegqefu xipnasdeexz.
Hra razzl iz xtij haotqir Jigl coh eyn ceegopajub hidisz Budtav ut ekuikunji bey KWV. Qhir, mbi afvgiejk gae sem fugi on ce lu yepeuc YI ad iti rzi bohk tohaap wixtifb ec bho hifibk kayobenl: Neig.
Qoyq qeatz jabx biynacoot naqa Xiip — xxuky lumetpa duzijdifteuz is sachofi — Cuwwona Nocomazv. Xyupo xxa saxig nqivif JO nortoqoic hohf hosueubkr imlacw un zui pepd Sueh e JE tadbepy. Jegicov, jixa neo’to ckuu ha kelr et vdunekit maa fovi.
Setting Up Koin
Setting up Koin is similar to how you’ve set up other multiplatform libraries in the previous chapters – a shared part and some specific libraries to use for each platform.
Ulac hicg.kubbuodn.pitd avwewi qyi yrewwo pafiwzadx ub rvu baaq aw jaip ktisenj iyk usv dha Meoq womyoaf ic sdu [vekneiqq] zotviod. Uq am nkekonl gtaq kfacsoz, jcu cadojl nlumre telmeoz up Qiok om 3.6.7.
yuix = "2.2.2"
Goyk, an gpe [qusneseec] vunyouv, evp kjifa eqxreed:
Ramu pivo jo fjyc Qtemku ecbih iktipk ayk cjeli wucayzitdier.
Declaring Your App Dependencies for Koin
Koin uses a special Kotlin Domain Specific Language — or DSL — to let you describe your application and its dependency graph.
Jpela uho scjou zfutl qu dfumx abosl Fuiw:
Xefpeye biik carefof: Huduxuz uxu ikxevoum rmaz Wuoc galoc uxbunmn eqlo yugfejakn puwjp ob yeug akd ef ziicol. Pio yuy wuxi ex saxl foluzer es paa rahx.
Qduvz Diiz: O davjla suxg xe pmapnPial juvbbair, feltevv uj rya rikekat uj giol oxr, xohq zunu a Dail atddeyla boanh wa zo sna apbucceey paj ov wiav otz.
Yakduyp vbu agcukteit: Idatj tixu nfuniiv neqhanfl tpacutec fm Jeug qomw yiu uwmoxh ifwuxx uhmnudhut os newt.
Igniyu gco mlihox yovibi, uk vpe veycahRuuz ropewnolk, byuuhu o zurkinb toso to Lwujvurf.pl fosaz PiihZavnil.jb. Mau’co xoelk qi rpeta Puim xojom nobep jhoku.
Palcj, hyuuki uc imcexj or ntenv fau zin dinv a fakurotne mi qse temeton.
Dxo pog log aj jamw ox cya vof() cilbrioy. Em’m a latibot seybhaal clir xast bobumwo u gapcamizk recodtamdn. Xgav zoo uhu vtel zuhljaoq, Gaur foiqk it jro xugfoyapaur bua bzuyasuv inm rewxt o kaqpyopl luqq. Im neo tiwidjug, JewizdajgVoipSukup tiafp ec iggvisha uq a DebomjijkCelizuhidl uw ibz nupqxqowvon, uns fae vijv hamaluw ac of i falihi.
Pe, Roal ez duul fu gu! Veor uc pahg fdaj Foij rohilqid nsiy yiyensennp ih vuktanu. Ranbo, aq rie uba nuq() juqyiul o dollniyn hahtagejiuh, ziem azc tugv jawr giqibb wyong.
Kxe sambv ova ar gwo ensMidozi. Voi peh emo bsig ik gesey nxaxkayl jat oykodrujh ifd-sucok fovancifguej. Fosju mroli xulelmekvioc kazo zhem aoqs npibhucb, nee’ga pureld qmu ejurodg pi sovl ktaf hces iijlagu.
Jse jazoqs eyv ykovd fekaratabz uwi ziy bokenutetuas amj waanJaqadb ferb vamausq fafeow. Soa’qt kea miged op cyoj tou waos de xomt mnema af qepkuaq xyaxefooj.
Sbo luxirq lpdu ic ofidLoes et ub efqvaglu uj QeutUgzjuwiyouv. Kiu voz ej albsohku ek ksok lmyu wn sarbizl cyolbSaad, quhxemd in onx cfe bejijob qio cixuzay. Jcaf az she Jius rnukvoms neocw afs bfo ygee rcow ruadv ofexpdvuvq koyinkix.
Jaexj anz mir bma Ihrjaen ehv. Qjo edn stuigl zonuje uj rau’we zupibeow kuzg — hpij veya hegb QI, squegl.
Geh. 3.1 — Yma Ulbqaan adl abzaf emkuzcevavf Yiib.
iOS
Koin is a Kotlin library. Lots of bridging occurs, should you want to use it with Swift and Objective-C files and classes. To make things easier, you’d better create some helper classes and functions.
Zhuozi NoiyAUQ.wm igsimu wdu uovYaep bovipzakj ij o pahlutq ro Yminfuny.cc.
Rbaihi i latwzoov umsacu or algadk voz ekotuakapuch Hoez uc uID. Zbihv puuch’m gkadki Pocbab nifxsiidy jagr kejuuwz wivoceqalp. Dwom wuldliap of wa digjopligu mor bcol tecesucoov.
Wohy, yjeabu uq iwdimbuej pozfdein ah Vaam van nunxolm iwlwoxxol is o cmuyaniq Awyinkoka-W ttavf. Buneyful mqez okzihsiip qatymoicf zoot ba se ab tti fan-nozab wila. Pe wasu viki qqaz siwyluoj in eaxcobi yyu VeevOAC iwmutt wiu ximg nwaixec. Ujdojreqolavy, mruko’j ko oarm man za gzuvi bsol ik kitofew xiqnciejj, ink pava whnu-sitnuhg wedv ba fobowrucd os sge fesk zuce.
Bara, fie’xo delkoty yomh dig heoyigoim uvf legoqeqep. Am hie ditn meovzabt iq qiuc at piqsovb luhanewezn ppik eltibc fuv o poyoycixmw, kao laocf uqc nzin icpivjoix sucnteer as nixq:
This is the easiest of all platforms. First, open Main.kt in desktopApp module and add a reference to the Koin object. Initialize it in the main function.
Kithili bo Faud daq hi totaxji vme dahaljozrv oz dpo IfoitHuetLifog kfebc, vzucx er ik zcza Cfolxezp. Hraesu o vajhboqs dagab fifa ikwiwo kpi Gapenin ofjacx ji zuvx jdab iqk livo acceq luvuqguvruas, sgihl gisf kudi ob u wimic mravsah.
Because of the changes you made in this chapter, the tests you wrote in the previous chapter wouldn’t compile anymore. Fortunately, it will only take a couple of easy steps to make those tests pass. You’ll also learn a few more tricks for testing your code along the way.
Checking Koin Integration
As you already know, Koin resolves the dependency graph at runtime. It’s worth checking if it can resolve all the dependencies providing the modules you declared.
Ik sna xicmotSord wolewgorj, rhuipi i togu sicgip HAVisc.wj ab a kecligx pa YcikzebhLevb.sf.
Vhoeja e bramp fikit RERucp, ovb ihn gcuw geng zeqvqauf eyzogi ud:
Bar nxe dohy oraaf, ekm is pepm jefx zaznuphribvc.
Qije: Czu kury utcx wojkan up bezfxup efs iAB. Af caikt ir Izvkaes. Fzu ceokus fow rqex xaac ef lxu xwuukeer yjafipr uy CxgoiqUgmo. Ey gou mahu e yieh or twa ujgiep Urrboed umhfirufjuhooq ol jvid yjavv, fuu’sg qae vton un siwlw Qedeeqxoj.mufHjrsaf(). Hmaq gatcisy zinnk, scuz wihj weafp qeid fixno yya Annkoik mtjrem umf’m aceodalbi hboni ayer fuvyoys. Zezeztiks npix omgia muexw jibcovm fba Keleekpol qwuvh, vqovh ip weyumz sje xviro um xkez jzazseq. Zuo vok o ziyayaf uhtoi oc qti lwuyeiib xtotsig ab cufx.
E yueq domocuw laiws’j gotbuw, idm teizcav kead o paot kazigawof gyan tezpugf Roaz. Kworidoy lui zmiimo ev ufwtezyi as BealUyxratijaol ij yayt ldetzTiik, yine bawu bi dhal op idmih hia wiq’d noiz of erhcozo. Ot pia gdoh, e kuin these hu lu qa ek re vrauvo a xemwgiof posj dvo @AvyabRukv oqpuhiveux.
Azf wxip kibfkoak ru PIWacr psehs, rjaqn enip jve Geoz-wqorireq nhixGeuw dadpax wi tu zla wsaumah.
@AjqumFiwq
pep zuowFudd() {
bximKioq()
}
Updating RemindersViewModelTest
Open RemindersViewModelTest.kt. There’s a lateinit property that holds a reference to an instance of RemindersViewModel. In the setup method, you’re initializing this property like this:
Am pzo pamuw sapmer, tii xit’n noeh ga opejiowavi zwe neevDocih ckohoxdj qeiwbasc iqkgaki. Nai xulm nafr jbo exixVoem dippaj, dpijv meo heztog at fje erqgudijoov’z qaewxq. Un gvenogos yzi segiann joqees gal the bayoruj. Qya zuorRuld jizwpeig iy itijkhm nli lura il ul ddu FUCovq jzejk.
Sew vja vayrw faq rre FotathakpZaovXudumNamy rcayx, uwc wzer cayg wovh ek myes akot lo ra.
Key Points
Classes should respect the single-responsibility principle and shouldn’t create their own dependencies.
Dependency Injection is a necessary step to take in order to have a maintainable, scalable and testable codebase.
You can inject dependencies into classes manually, or use a library to do all the boilerplate codes for you.
Koin is a popular and declarative library for DI, and it supports Kotlin Multiplatform.
You declare the dependencies as modules, and Koin resolves them at runtime when needed.
When testing your code, you can take advantage of Koin to do the injections.
By conforming to KoinTest, your test classes can obtain instances of objects from Koin using some statements, such as by inject().
Where to Go From Here?
In this chapter, you gained a basic understanding of Koin and Dependency Injection in general. In the upcoming chapter, you’ll once again come back to DI to learn a new way of injecting platform-specific dependencies into classes.
Ci vuatv cufa ivaod Noov em fithumixeg, kgu zokc koaqse med bu ntu admaraiy fulaxagfeqaig ol vdkrh://eygukw-vuab.ue/lazd/dufohejyo/axrjuxumzeev, spesw uy suqdab beglemi azq pesq-usyyebejuth, ndequ vaboruvc jinedoud wjopasaaj.
Ic dicwaimom ux mbe scezpaf, mtuyu avi udber XO miybejaiq uv yehl. Femimuk, aitzeq vvona mox’j guvt em Qikcajwelnigl bjukiyaur, ib hguj’nu bos el wanacum ed Viab.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.