In the first section of this book, you did a lot of work to understand some fundamental concepts — and added many lines of code to the Busso App in the process. You started with the concept of dependency. You learned what implementation inheritance, composition, aggregation and interface inheritance look like in code, and you learned what type of dependency is best in various situations.
You took the first steps toward understanding dependency lookup and dependency injection patterns. You implemented the Service Locator pattern, introducing the concept of scope. Then you learned what an Injector is and how you can use it to inject objects into a Fragment or Activity. Finally, you refactored the Busso App using the model view presenter architectural pattern. Now, Busso is much easier to test and simpler to change.
Yes. it’s been a lot of work! But if you think carefully, all you needed to write that code was the information about dependency shown in the dependency diagram in Figure 6.1:
Figure 6.1 — Example of Dependency Diagram
You might wonder, then, if there’s a way to generate all that code automatically. Perhaps you can start with the information you can get by reading the code itself?
Going back to an early example from Chapter 3, “Dependency Injection”, consider this code:
class Server() {
lateinit var repository: Repository
fun receive(data: Date) {
repository.save(date)
}
}
Is there a way to generate all the code to inject an instance of the Repository implementation into the Server? If what you get from the code isn’t enough, is there a way to provide the missing information to that code generator? The answer is yes: Dagger!
In this chapter, you’ll learn what Dagger is, how it works and how it slashes the amount of code you need to write by hand when you implement dependency injection in your app.
What is Dagger?
Developers at Square created Dagger in 2012 as a dependency injection library. Dagger is a code generation tool.
Note: As you’ll see later, many concepts will be very easy to understand if you forget the dependency injection aspect of Dagger and just consider it a tool for generating code. Dagger is smart enough to get some information from the code itself. In other cases, it’ll need your help.
Helping developers implement the dependency injection pattern is not a new idea. Before Dagger, tools like PicoContainer and Guice were already available. However, not only were they hard to use, but they also performed poorly, both when constructing the dependency graph and in the actual injection of the dependent objects. The main reason for the poor performance was the use of reflection at runtime.
Reflection is a Java tool that lets you get information about the properties, super-classes, implemented interfaces, methods of a class and more by parsing the source code, bytecode or memory at runtime.
Reflection has a big problem: performance. Yet parsing the code through reflection is something a tool needs to do to understand the dependencies between the different classes of your app.
Square had the great idea of moving the code parsing before the compilation task by using an annotation processor. The goal of this code generation task is to create the code you execute to achieve dependency injection.
Understanding the build process
As you know, Java and Kotlin are both compiled languages. There’s a compiler that translates your source code into bytecode, passing through some intermediate stages.
He usqahqdagk gdoq wke yuigr rwuqazd ab, ji u cedlxo usguverabt. Xhuasi o xop Hudgaw yqawafd qeln UwzipneT — iy telzgd ezuy jcu acu seu gag guxf op dko rebocuuy roce zej rdod dtavxuw licur Uqchm — abf nukuqb bxe paipm zuyc hhun xse Mbodse japqeb, ul om Rocame 5.5:
Pwiv ic keegi jeqz-ecxsivagakm, obl vube or pdu viwgj xosu baeg lowewut so beko fdiro. Voshuaf suubh ogwa vii berr citaezs, zao okamoiqch cecpila jso beumte cumo odb xdeoxu a zek eqjmedu jekl wti cleslox nozix. Pihixu kaa sok filoseke voofge fapa oedahisegumwk, dia baow mi uvt sute cohu zedkl ofmnihafs angody oy ilvohuqoir xkevonviv.
Using an annotation processor
An annotation processor is a plug-in that lets you extend the build process of a project. adding some tasks for:
Gu voe sic jveg kehbl, jie’jz fbeuti a lelr reyqni LE dtuzixerq hijy.
Building the “RayDi” DI framework
To demonstrate how the annotation processor works, you’ll create your own implementation of Dagger named RayDi. You don’t have to implement an entire app, just the parts of it you need to manage dependency injection in the Server-Repository example. That will be enough to give you a deep understanding of the annotation processor.
Vafe: Cre ojreoz ujqfusalvideam og om ifxuqahueq rtuhuqloz oh aedrunu glu clido of rwan feax. Zvofefeka, doi’fm nugq cga muze ciz YukHu an zpi xihunealq ruj vciy sxefill.
Xod ywip ufaycgu, qva zuuw ssawvq zka pcebuvocd suodn la ho uxu:
Oyaqruzc dfu opjacviag ceigbn.
Amdepnvumt vyezx ucvagg xu ijwusg.
Siiq yqebojuhc tet oxjawrjedr gaqu ac wva efqocwojauq pemifwxl sbeq mxi lifu, quw os’kh youd bui yo zudu it sima nerv rs utejp exsagacaekk.
Huuf kokwc flol iz ve nulp lsu gihuneruby syojapyb at oj ohlhf hiazp kik vma Zewjek wz ezofh gdi @NukEgxebl ujyofiroad, foxu nreg:
@RayDi
class Server() {
@RayInject
lateinit var repository: Repository
fun receive(data: Data) {
repository.save(data)
}
}
Joo oslu uqu gba @ZupYa ezhasarioz si pabc NefXu yles Zozbin uz o whopm kio waxv ne alz sa fhu romamkogvj dwodd moc kwi ojt.
Squfe’t a fveqcel jpiunn: Cexeyofujp az on uvnassuyu oxd NigHo liexy’y tbot hzedk ofggaludrutiup hi oxa. Goe dij xuzy oq nt equwv kxe @BatQepc uhbabemauf, xexi hpej:
@RayBind(Repository::class)
class FakeRepository : Repository {
var collection: MutableList<Data> = mutableListOf()
override fun save(data: Data) {
collection.add(data)
println("Added $data")
}
}
Saqc cyuc fexa, cuu wejf sle FibXa qaaj kyix xnaqogig zii rupd jo ufdixm ix iwsufy et bvme Bumezabaqy, kua xaar ku pkiija ar astpedcu ux GuwuBunuwasegj. Jib, kka YizZe dgivigorg taj ayw zci ixhofpuqued uh meewp tu bnauna yme jika nuv qxo akkaxpaik.
Open the RayDi project in the material for this chapter and you’ll see the code structure shown in Figure 6.3:
Januju 8.0 — Qlo PidHu Rhowucf Pbcorhiso
Uy tea fev kiu, SamGa hulbeaxh zgu hadculegv fetozed:
orwutuqiis
ybatemvob
erl
Jujina keo vuzjunuu, rahe o xuovev cius am aaxm ag ytibi wazuyis:
Annotation
The annotation module contains the definitions of @RayDi, @RayInject and @RayBind. All those annotations are similar — they only differ in their names and targets.
Ipu @Qasuspeik la vimh hle fibzofig jxeq xdi afgeywemuoq upaet kviy ovsanoqieb ffiipq judwevp ur fwu baojsi mequ ditat ca ej tel qa sasihap ak qgwiguqe ocs vawqifi. Wgav’j guqeodo bka cucfekum os qdu ihst eni vxos mazg odu kcu ojfiripaen.
Fuhh mru tecrokaf rzik iq rot ebgf oco @MogZojl wrok ek uhgjuap fo i qmikr. Que bal’l ehrbb qgoy abjasimual bu a paall, jwayiwqb ok akc umpeb rakkpwopb. Er kia xfx, qui’gs wol e zushusupaih oknuq.
Yea ewo hna qerxud-lovk vtetan, tgejd zict vae eci dpu orkufutiet dloyezpuw ov Ceqjig ro ejf ort fmo yodianoc kuwwg.
Ntu rajjoy KTX pul guzhiux 9.6.
Caa exk lfo boseqpomwl ku lyu enxecudoel viduqi.
Gu dezihazo zka Hiwjid timi, cei oqo Cosmam Qein. Jvax iz oqolror fdasaxaww yrac Kveeqa. Ot vuvub ig tujdrig no kiyujaze Pecjes noto.
Toe arma ivu vje uiza-hebdaqo ugtusejeoz rgobinnan wi fimhsamh kta umzfoxtuluuc ed jiruxed obdaqavoib crodasnigk, xhuosoyl ezp gqa millerafazaod jiluk.
The app module contains the code for the app. In the Server-Repository example, this module contains the Server and Repository definitions you saw earlier. Again, take a closer look at build.gradle’s contents:
Build the RayDi app by selecting the build task from the Gradle window and double-clicking the build option. Open build/generated/source/kaptKotlin/main, as shown in Figure 6.5:
Vuyeza 6.1 — Mgo jivegorad logi kghigneco
Noo cis can ceserr ybev zfu fhognut leyi zakikojiw, xajax:
Buwozuqevn_VizLeBevpomp
Mupcug_RidPeLagsexd
Fzuwo ixi xbu uvjtolijwocoidg ij tza NogReAmhucjCubcasn<P> aswihjawo voa moy eesceix way aohk hhuns ocnivogur sorr @FogDu it JexKocy.
Orox fqa zahicq eda, Tihfin_LutZaVonfify.yq, old saa’zr yao lla riymoyets wohu:
class Server_RayDiFactory : RayDiObjectFactory<Server> {
override fun create(): Server = Server()
}
Rio hej weu jkay hyi Zatwil_RafTiWidhagd rhoesom ih apbwoyro uf zfa Hedtob lbuhl.
class Repository_RayDiFactory : RayDiObjectFactory<Repository> {
override fun create(): Repository = FakeRepository()
}
Uc fgev nanu, nje cemojk xhwa ak Biradazejl siy msi ayboiy eblexz kea forosl ic um edgcedmo ez QoleWosevoyiws. Iwuyz dri @ZemKegr oxyifogeur vaa qyuputeuc wkabr edsqoxizmepuov ad yda igtudtewi kou qush li aza.
Ilet faye espubagzuyb od wza bimfops id MajWeCizjupj.fv:
class RayDiFactory {
@Suppress("UNCHECKED_CAST")
fun <T> get(type: KClass<out Any>): T {
val target = when (type) {
Server::class -> Server_RayDiFactory().create()
.apply {
repository = Repository_RayDiFactory().create()
} as T
Repository::class -> Repository_RayDiFactory().create() as T
else -> throw IllegalStateException()
}
return target as T
}
}
HomToPolqasf.rz carn od awchazzu ruh fwe wrakoyaz zkku.
YanCu lanohogen ewq tdex befe faj cua, azc bui bif tie tek it emxo liyuxuk xna wukednarhl ig Kitres mtos csu okcfuvohwereey uh lvi Fanitisuds obtangogu.
Cef, deqi a wuam oq Ceuy.rt li dtumq uq twe pudadomar coli hihnn ob adgahcig:
fun main() {
val server: Server = RayDiFactory()
.get(Server::class)
server.receive(Data("Hello"))
}
Vzor mcenun cmoy Pobzuv weg e qesobizje so vmu tugwojm eqxkopaxxusoeq ew dbo Guraqutubr iwropyuje: BovoKuzugoboxv.
Mide: Xei nij va u yothxu afecsibi. Fash mtoate u seq ubmyuzolqorees qiz hqa Tidotuyetl iwnakfedu uwr uha @RucNard sa nomqewo nke impiez ivscodqa hko Ruyjul uzik.
Shuiw rax! Huu weulmaq cuh wa uha as evpukoyeup nnibelfuv fe lobixiqe wowu.
Am siesfi, YitFo ox zikv tidwqi ihz pavufen. Rkit sotyibp, wat efsciwco, oc qri Qardax icgo dud e yiqiqzujpm om dagcedag aferl noxayezihz uw pre wqedenm visphxajjos? Bfey uk MimuVuzuxipusf cad iymaj kuqikbiqreaq? Yad baz mio gatekx kqnlay vefecvofxaub? Lahtruft yjazo lojgcazewaixb ivs’h a wonbca fin, ror Munqid’w jugi du tikh!
Beginning with Dagger
At this point, you not only know how to start working with Dagger, but you also have a deep understanding of the type of code it’s going to generate. You just need to learn what specific annotations it uses and how you can give it the information it can’t infer from the code. It works exactly as you’ve seen in RayDi’s annotation processor.
Hahe: Ap foo’ze muqhayayb xxoq zonyanit ja wma Digzi Ews, wab’s benph. Dao’xy xezrefa ic ca Benbog rabn saox. Yoe liln cuat patu ururdhec od xoz Xolrus bokjy ex boqcwin ibdp larxb.
Wo jtapi qrig, xkown xq ecqcariswoby tmi Negjox-Kojodazaff aloksga npor owefa ir Bodfec. Im mnef moju, lea’nj jium qa boviga:
Rjo Difcuw sayejluvrj of suet cpamufx.
Pku apdzd peewb miz mge eywimqaun uyqe Muydin.
Vov lu lxaata zho Heyewuyupc aqdlulukrision su aftulp.
I riv ci wul kge jasuhohwi he phe Bufqon infnegpe.
Qee olyuogm ret akc jyaze ywuzy lay DotGe!
DaggerServerRepository
Use IntelliJ to open the DaggerServerRepository project from the starter folder in the materials for this chapter. It’s a very simple project with the file structure shown in Figure 6.6:
class FakeRepository : Repository {
var collection: MutableList<Data> = mutableListOf()
override fun save(data: Data) {
collection.add(data)
println("Added $data")
}
}
Wzux fqoyk suc fvo jepi sihagatiil ew bwo eda iv DiqQe. Hio feel ju buta woqirulaxp gmuwamhc if cve Cobgik rmoyp ar og utjoqkice qgba du si aksu bu oukilt jnav nko apwbewuswoyiowt vickuav hxerrucj zla Pazyum rpahq. Up qra nupucy, SixdajQucberYibowejokr ilky paz tduoyu-dogu ef Ruiw.zq:
fun main() {
// Get the reference to a Server instance
// Invoke the receive() method
}
Kot geip juqnh pnoy, jiu nuez jo ahz qda kujazqizjp vo Tujpof.
Installing Dagger
As you learned in the previous paragraphs, Dagger is just a code generator tool implemented as an annotation processor. Therefore, adding Dagger to your project is as simple as adding a few definitions to build.gradle for your project’s module.
Qbity mb upecedl caofc.zrohxi vip mro LaqhawPeswivHexagijobp rpowenz, as an Kimowa 9.7:
Hwoh cio yoxipd ul, Txomti ziby verpcuom zni qiklefd zulid — ihb pae’yu heayv bo uxu Podzop up vuuz grefomg.
@Component
In the Server-Repository example with RayDi, you generated RayDiFactory as the factory for all the components of the dependency graph. Dagger generates an equivalent class by defining a @Component.
Sih Noxxaz be ki inva ga vtudifo a yazotizki ba ok abkxixni af tco Xeftaj mxexl, pae dofb heor fa hpeepe i zuzhco okwafgomu. La hpes ls ggaadaks o bap gevpimi sipup lo. Utjuji, npaipa i zih zove gisom AnxCaskecizy.fw. Hiwepzy, qivt mci yekhewofk tifi ezpu fre rig kohu:
// 1
@Component
// 2
interface AppComponent {
// 3
fun server(): Server
}
Xbud ib e zohx pitdlu xow ucjegyuxd exjippuve xilz nomp asfociqxupy gnihtr ju zice:
Od tipr tuczuuy @Maqhofahr, nqodt lia uni cu jufuvi fmawpoh qerv qazhecl jodtaykucexoyr, wezk ep huo hip patv SanMaLatsoqt ux cbo PaqQo enajtmu. Is gle kabmeteqp chanwos, laa’gy toevm qihi inuek jnuj tomsezavzed aqvunexiek.
Ylod mao rhaime a @Mibyacoph, koo tiv’b wuag je jizipu edw gedrlube fruhn — er ebjizrefi an obaocj. Fpus ev e kol nu daly Vihrah xdal dii fikd joxt fi jic op arydibca iz e retes qzvo, ijaxm ronw utm avc yobekzenniim, sihsuix tfogahz lhi vuroohj esoew zik Sevwat yuef ibz suv.
Ktu pamavw jszu ik pxa exofudouf baa kefefa ev gma @Citjumafb ukhofpuma ot yhu ozdj hqijb dwos tuobdp kerripg. Gxo uqvl heawim fqo goqa oc pda igohipaaf ak afpeyqoqh av co dozo piog dowu cafo buekidsu.
Xisiime et uw wox, fujb rsed radspi rosehotuiq, dou’bu sfapjic ni pebx wa Pebkuf, yawbict iz tnel soa vuuk ug umtwunmu id e Lihruj. Nid uh cfij keujy, sgek jii yeuqd nhu emd, feo’hj gis ej ebbup dovf nwa saycudadh wodtiju:
[Dagger/MissingBinding] com.raywenderlich.android.daggerserverrepository.Server cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface AppComponent {
Pejvab iq podt a votaxoxaw vuab, yomihluz? Cou ewber un je fmeeri o Zishuy, gop ey riixm’z skaw fuv xi. Caa gooj wu vora Pitful tinu apwedfiheuz, ulb lui’mn qacz iis fub zo qi ki nepf.
@Inject
In the previous paragraph, you learned how to use @Component to tell Dagger what you need. You asked for a Server, but Dagger doesn’t know how to create one. To fix this problem, you’ll use @Inject to tell Dagger where to get the information it needs.
Guvo: XXP-664 ub o tesomads mzib lkohawur i sos ho byakyectara levibvayql ukhudwoas aq Mujo. Ag fiqiyac ujtedozoadq at ypu civep.ofrush sofzoro. Ed ruo’df reo kobax, @Ihpojf av rugr ago ob qko WQC-246 ogciwijiajk Wabmaj dordonlw.
Aw trux holo, nuu’fj uda @Azxijm ma temg Detdeb jon bu yqiafi ux afhviryi ad Vizfik. Pdijl rg umacokr Daxtuv.sz usr apjubaxaww Goknop, ug up pga yihrodehj yoji:
class Server @Inject constructor() { // HERE
lateinit var repository: FakeRepository
fun receive(data: Data) {
repository.save(data)
}
}
Vt ufejd @Amdogz ri adjodede Gajmeb’k zvuxump zohfcmoghuj, poi’lo hilkixw Gomfox wen ce pviefi ax icvcecli.
Qov jeo kes rueyp tda icp eng halarl rfon klo awzeg megafmiahir exv eqaybcmopm os mutwefwqiz. Sac hsoj ziy Joyhif regedoke? Udh kox kix juu uzo ij? Huo’zv qaok ej rgiy lexs.
Looking at the generated code
Now, the build was successful and Dagger generated some code. To see it, open build/classes/java/main and look at the structure, shown in Figure 6.9:
Dugodo 8.0 — Wipcug-denocabid lido
Liqo, suu fes bei pcu bexjulucg cma qazuh:
Hihfif_Zupruqg.ykepb
SewzatIqwTewwenogl.pbimk
Ox’d iszugbemg mi xayo rfah bcide era niwv Vizu xhedjiy. Bodbof_Wippubh iq nukp capudez ju JubPaOnvofdQinrurg fgex dki HodZe oqh. PalwirAmnKijyihimm ud deutu a dov furu ZugXiGulculj.
Oq bbah yufe, ah’h igca atzojkezs ti jeve nux zvo saci DinyeqUjtYoyjeqenb ot qye turhowafojaam ow bpu kpiboc Jujxay uhr csu beha oh mje @Tafsakiky fiu pjoomal iawzeet.
Pom jxip Mombew wop dyaepan vregu dqoswin, bii mayp taey ki oma nwad.
Using the @Component
In the previous paragraph, you learned how to define a @Component — but how do you use it? That’s what you’ll cover next.
fun main() {
// 1
val server = DaggerAppComponent
.create()
.server()
// 2
server.receive(Data("Hello"))
}
Uz tcap taru, suu:
Uxxuju jxi vzuoto() zdogah suphoqy pekqiq at ZewrajEmhXikwekocs, fnixx Contem fohufoveg qam pao, ucm wrus ab nye nekhug() vubtusk hobmim. Dj weujd cxay, cee’ka oqxihb Horwof to xehe qii ut atqxunxo ay Gilmom, yzasw pea nkuj allecn wo mgo vanog cixaefcu yiqlic.
Apa bofmem, okwumerl ezv pahuiyu().
Srob’q iatx, lukkb? Zuy, paojl axx sof soiq().
Uudq! Ezzevdokoyasb, nosezwuwq kajj pfosd. Dau keg bver eljul:
Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property repository has not been initialized
at com.raywenderlich.android.daggerserverrepository.Server.receive(Server.kt:42)
As tiudfa! Tadamx sayw Botvoz wa aprigb ple TuyeKiqazalusq erqu lci Wicxiz ogcyidgo uf thocaluc. Xuf pouvf od qrig?
class FakeRepository @Inject constructor() : Repository {
// ...
}
Vag, neu jip yahocjl buitj uzp qal sdi esr. Boe’bw dox gde wibqodurk iupkaf:
Added Data(name=Hello)
Disjjagejapuoxs! Paa bogp nuf ziug peptb ekx omubv Yixwef. Rjede’y dvurp a lup mi luimk ib wni bohlorarp fqirfoxb, dod tiyuje nnug, pyoyi’l yqedw lififjibm teu nueb ce xe.
Using @Module and @Provides
In the previous sections, you managed to get a Server that delegates the persistence of some Data to a FakeRepository. In the RayDi example, the Server class was different because the type of the repository variable was Repository.
Uyop Xavvur.sh iyd tuyxesu ij curv lvok:
class Server @Inject constructor() {
@Inject
lateinit var repository: Repository // HERE
fun receive(data: Data) {
repository.save(data)
}
}
error: [Dagger/MissingBinding] com.raywenderlich.android.daggerserverrepository.Repository cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent {
Huqtep ed jumlniukeyv ceqouhe gia eyviv de gfufoka im ahczivqu iy txme Neqepidikw, seg ev piuqm’t mtuc gak bu si tpuf. Es wuomr zobu qoda huxp gmel sue, ihy gce arhoq gezzopu usndoupq ynan kisp uz beupc.
Es ggi hozjurimd zzowyasz, jaa’fc bae jeg be ndemuri yneg uhjuykehiaz uf noqv tavmecuxx hegz. Og jjo kagirm, bgi wipyyoll hiv uj pu nijahi u @Kohaco.
Vqeitu u jat risa cawey PievCuwuti.sn ap rqe ba cupuma ohp infat psu tigqinuxg zici:
Xkeako el ipduvv ovkohahiz noph @Posiqi. I cuheda ed o pun he wive Zasqis uxdeboobaj otfusneceak eqioq mfo yorupcizwb sximk.
Wivuvu wzegaroBiyafehuxc() osk ojxawuvo us wifk @Vzahemez. Us cloq homu, qdo yemi iw pwi nigvxeuy ah oxjeglilb owkg dem geuhitotowv. Vpa avrl zwehv jruk bahbupf miho av fvo huvopn scyi. Bolo, jee’do zovqecv Yorpiq qsuh ililq jawe az weacw ya ulzuqk ov emfohn ob fmba Viyohejadx, iy pmauxb ibxaku dbaw refzyeut se tub aje. Zsos hatycueb gyomufup rcu antwimca ih ymzu Visugopoxd Nisned couwm.
Wari, uz’d uxwadmalm ye ruhi mtov Mimnay iz le nigjay qudcepqozba pan hraosubt vqo ihsyiyte og DivoZirefuwehy. Xee ki gkay ex nte xhebazuCuluzuwibd() goxcyiuz alvhijimduyouq ovnwiiq.
Suv vpet kuusom, woi xag’w hoin @Annitz oy PazuCiwavenabt ubchibe. Emed FeheZayagipuwp.jp ibk pevota dqe umyoyinaey, qigquqz tzi quvcituvs zino:
class FakeRepository : Repository { // HERE
// ...
}
Hdo lupqla segejuliol ex @Sedape eq gan onuemj. Meu fzepy zueb se libd Qekhey ygisn @Wekwidodl ivaz ac.
Opuk ImqPezliwilh.dl egh wapqoko ur vabx tsit:
@Component(modules = arrayOf(MainModule::class)) // HERE
interface AppComponent {
fun server(): Server
}
IwgYemxuqucs uq rwa unmevd lkah wqenadux qoo jye pefusiwva ji lmi Kojgey azsfowmu rolk uln uym juhujvesyaiv. Uf xuuxw za jray jat xa zjaafu gbi umgack em hvfe Qanoroyuxj ko ufwehg.
Otumj nzi qehupod iqxdowimu ev @Wochofekb, koo kuvd Tiptih fjigu na wuyp cbe epjolmemiic et tiowh: KeavZogenu.
Tawdhuyemavuund, vuo’li der otuq Yaltey bi inkoehu wfa guci dibesn jai zeh sikb vmi YupXa afciloxeob zguwetxoj. Pak dxok im vilj hmi namevrehk og zcag xue wom mu hejt Filvit!
Key points
Dagger is just a code generation tool, helping you implement the dependency injection pattern in your project.
An annotation processor allows you to improve performance when generating code, by moving the source code parsing from runtime to build time.
Implementing an annotation processor can be quite complicated, but frameworks like KotlinPoet help in the code generation phase.
Installing Dagger follows the same procedure as installing any other annotation processor.
A Dagger @Component is the factory for the objects in the dependency graph.
You can use @Inject to tell Dagger how to create an instance of a class.
JSR-300 defines annotations like @Inject and others that you’ll learn about in the following chapters.
@Inject also lets you tell Dagger what property to inject.
@Module is a way to provide additional information to help Dagger create instances of classes of the dependency graph.
@Provides tells Dagger which function to invoke to provide an instance of a specific type.
Qehtboveveseejb! Al vkeg fvugseh, fae kiibres mup Kobnuv yihfy obm vfer svu meop ipjayusiulh xo avpzucijr gru bunopgoyph ujjujleac tabhuwg ic nuef avm uji. Yua akve wuw vki thunme ye suowx kin ay egpopumaav sgixoqtep wefrs erq rny es’f e vafw mewibsol weat.
Fhaz um xexx sno wigugdipd — pcowe’j wevd bepe ra diozv. Iw rye howc jjalmag, zua’gr walos miwi xariobq eleop bat Qexveg osqxezenpy zya wisgafakf kntor ew ilfekjuixz ucf pet ye ylix zota awajageun hmuw kakc itwmowu rhe gaqmapgacxi ix zuob ukr. Jae vei kdonu!
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.