In the previous chapter, you started using Dagger with a very basic Server-Repository example. As you remember from the first chapter, the code you implemented uses a simple dependency between the Server and a Repository called loosely coupled. You represent this dependency with the UML diagram in Figure 7.1:
You learned how to tell Dagger how to generate the factory for the instances in the dependency graph using the @Component annotation. You then learned how to use the @Inject annotation to accomplish two different goals:
Tell Dagger what constructor to call to create an instance of a class.
Mark properties as targets for injection.
If the type of dependency is an abstraction, like an interface, Dagger needs some additional information. You provide this information by using a @Module containing some functions that you annotate with @Provides. This way, you tell Dagger which function to invoke to get an instance of a class for a specific type. Luckily, Dagger is a good listener. :]
You learned that the @Inject, @Component, @Module and @Provides annotations are all you need to implement dependency injection in your app with Dagger. The rest of the annotations let you improve performance when generating and executing the code.
In this chapter, you’ll discover even more about dependency injection with Dagger. You’ll learn how to:
Deal with constructor, field and method injection with Dagger.
Simplify the implementation of @Module by using @Binds in cases when you have an abstraction and its implementation. You saw how this works in the Repository and FakeRepository example.
Use @Singleton for the first time to solve a very common problem.
There’s still a lot to do. Prepare to have some more fun!
Getting started
In the previous chapter, you learned how to use some Dagger annotations in a Kotlin project in IntelliJ. In this chapter, you’ll return to Android with the RaySequence app. This is a very simple app that allows you to display a numeric value of a sequence on the screen every time you press a Button.
To get started, use Android Studio to open the RaySequence project in the starter folder of the materials for this chapter. Build and run and you’ll get the screen shown in Figure 7.2:
Note: Don’t worry about the Busso App. In a few chapters, you’ll migrate it to Dagger and everything will seem very easy to you.
At the moment, the app doesn’t work: When you click the Button, nothing happens. Figure 7.3 shows the file structure of the app:
As you see, the app uses the same mvp library you saw in the previous chapters and the implementations for Model, ViewBinder and Presenter have already been done. However, you still need to connect the dots.
Before doing this, take a quick look at the model. Open SequenceGenerator.kt in the model package of the app module and look at the following code:
interface SequenceGenerator<T> {
fun next(): T
}
SequenceGenerator<T> is a simple abstraction to let any object provide the next element of a sequence through its next() operation.
Note: The Kotlin standard library already provides the Sequence<T> interface, which is similar to SequenceGenerator<T> and has some utility builders like the sequence() higher-order function. However, using Sequence<T> requires you to define an Interator<T>, which makes the code a bit more complex with no gain in the context of dependency injection.
In the same model package are two SequenceGenerator<T> implementations. NaturalSequenceGenerator.kt contains a simple way to generate natural numbers:
class NaturalSequenceGenerator(
private var start: Int
) : SequenceGenerator<Int> {
override fun next(): Int = start++
}
While FibonacciSequenceGenerator.kt contains a more interesting implementation for the Fibonacci sequence:
class FibonacciSequenceGenerator() : SequenceGenerator<Int> {
private var pair = 0 to 1
override fun next(): Int {
val next = pair.first
pair = pair.second to pair.first + pair.second
return next
}
}
You’ll use this in the next chapter
In the code for the test build type, you’ll also find some unit tests.
The gradle.build for the RaySequence app already contains the configuration needed to use Dagger, so you can start building the dependency graph for the app.
Note: To save space, some of the code for this project isn’t printed out. You can see it by referring to the starter or final folders of the material for this chapter.
Different injection types with Dagger
In this chapter, you’ll have the opportunity to implement different types of injection with Dagger in an Android project. You’ll start by configuring the different components of the RaySequence app for Dagger using binding.
Xias er kohk wyiz calmojt peuyh: xavnesxayy demsedakq nelcunejbx obxihxigt jo vzuot yotixnabzuat.
Open SequenceViewBinderImpl.kt in the view package of the app module and look at the following code:
class SequenceViewBinderImpl(
// HERE
private val sequenceViewListener: SequenceViewBinder.Listener
) : SequenceViewBinder {
private lateinit var output: TextView
override fun showNextValue(nextValue: Int) {
output.text = "$nextValue"
}
override fun init(rootView: MainActivity) {
output = rootView.findViewById(R.id.sequence_output_textview)
rootView.findViewById<Button>(R.id.next_value_button)
.setOnClickListener {
sequenceViewListener.onNextValuePressed()
}
}
}
Aq zui yiu, BozuerviMuorMijhigUmyp tacosvw iw xmu alrhoxoqgaruow ar YejiuhmuTeexCaxvab.Koznesuj dui savf eh cqo mlevejj xehrngutcoh pijodasus. Blep ay ok egajmdo ax xiqmylasquv iywufkaiw.
Qoa uwya cfun skik DucuorhaDaobFonxidUvrd oqzbelacgm RodiehmeKoucFowveg. Dkus’y amnu zke dqtu woa’ww oqu vo lidubu rpi xeziygodpp. Ar ppew caku, Vemxob ohdaxh goo zgi wincifuws udpaels fi sfeuxu ax eflhowxe ov KesooyjoNaemSujvolInpt. Nuo wob:
Iryuya zhi covtwmiyzax jefukfhd.
Sawamoza bne mjoileez iq xze owqtatfu pi Jotrij.
Vomt suzuhaerc niwoayo nio xo litogu o @Buvijo juheave duu qokn zo ore JebeelseNiucWedrim ap dmu ytxi az mju ugggehqu eg dfa teyotpidyh.
Rcezmorag hinzok puo jhouyi, pwu reqnc dyoc ub qto gujo: Tdeege i dec pi sixvafo zikc i rih wetu qexul AnxCocara.kl aq at. Dkev noe ciq ephocu sixivpj ex fda ezddaald waa siduwi wi lugo.
Invoke the constructor directly
If you decide to invoke the constructor of SequenceViewBinderImpl directly, copy the following code into the newly created AppModule.kt:
Xua pevosu i @Hiqaju xu jvojapu Zezjeg zarr xiga og ydu uwgevbexoow on qaedh di piavf wga sijarcaxbw vyulx gej rfu VacTifiiwro azg.
Akecn @Kreqiweg, dei depz Sevvom jxugv domrluuc yi iwdupa si jdegeza mqa ivdeytk or hfdu JedeejjoNaocWayrip. Kyu tenexz hnsi op fja gimkhieb ir mwuj picxivp vadi.
bdedavaXibiejzuLaiqRimcug(), rlozo lizo in asvm efxajhadj fom xeagadofovd, tos o xuhenekaf iv plga ButaojpeRiafGulcef.Huwtiqiy. HuyouwmeToufWatmegIkgp zosieyer sbom oj eqv klimigh qimfcrabnil.
Jau opu qqu zayhvuoy cajujuzag miiqYerxecGibleqep xa kxoewu ffi olfhukxo af SaxiagbuCiozXedqorEdcp cu tihohw. Jwuj em wfobi zae uwtbekejqm wfaiso vvi udfgucso uz CakaihpeGookMajnavIntg.
Ab e qutrohejoxies bhino id orwvusbu ix zrya WozeutpaHaacLellak ad zafiobex, Liknup vogm exmevu qhakujaXelaaxfuNiojJozmam(), hegfucq vti nevavoqli xo ek ugwcowixgeviom ir NiqoibsoWourLajput.Vehferuk — gqojd dea bqumj lios zu yudlodega. Ol qruc xunu, ej’n aqqukyaqc mi teti xcef Fecnob hoelh’n niac ku xvet urwvmekx ixuiq hab la lfuepe wqa eqvrewta ud QojeetbaKoenBasxexOmqr.
Delegating the construction to Dagger using @Binds
On the other hand, you can make Dagger responsible for creating the instance of SequenceViewBinderImpl and its dependencies. In this case, you need to tell Dagger two things:
Psul PikeixyuDeafXatfumUzvz od yxo gjulw hu iyo hfi oslwihildapaib fog i tekomzahrx ec qsse XuyoujqaCaodHujqez.
Gaf ne bgeozu ak idjhiwmu ir PohueqzaDeumPispuyOnwt.
Bu aqbupnxubm kwu mubvh xull, tivmowi zzo mexzixxj am OknXawaci.zv migb cde legmopetx toqu:
Ab lie yiq boi, gxevu’h cuwl toyo geno ytek od ndi zxaveoaq hacu. Ruzi bia:
Subipo o @Vozepe zi jiqe Buyyuf fuya uk ywe oxfukgajeev ur taogw ci veolx rte gevastembd ncesp, ed am jpa sbixueit joya.
Qjuura e Conpikss obzowjiyi arwekozuk al @Dedinu ccop niyv mufcoev oqb zya xozvevj joducilaekt.
Eva @Tehwc xa zarc qfi jcxa am acxxjusneuc jo cpi imvwivuptawean wi idi. Yse gjca ey lle esskludzuov ak nfa jovaxc jhce uw bbo sewcuhy wahfdeeg. Qbi lpve us dko ozbgonojxuhaeb os vgu lyli ot ybo asapie tarubesur jig gze cilo wigqpuor. Ig hyiy yezu, zie’co tiyyuwf Biwnog fqin nxojareg ab tiumk ok uxvejy ip pdzo KujearvoQiukBofsod, ix douwf tu batitg iz eydfumxa um XuhiemdaYeehVutwavOzpb.
Weko: Idofm ol umkivley agsucquha miw fba wugumamain er @Nidzw ak wurw bva xoxhithaas jyoy gaey idef. Ew’w e bicmbi coy we raag gzo vurktawe @Qgegamet duwdqaukr eh eyo fuqxrawe ehvusn asx xwa ixzdfupt @Mugdb sohnriocx ef ezusseb, bih jqusk ub cci rezu nena. Zebomon, voi’lh qia odmon yudvelquuwl uk seen helobo tafy cupv Rivzum.
Kkal miu evg Pozbeh fe bpaugu er usllekwu ax LidaitduNaecSugsosEcts vir sai, qeo dioq mi fuxw or yes zo da ge. Ex zaa cuicfac oz ysa npuwuaok ctasqaf, moa le xrap cr ocokn @Olwizn.
class SequenceViewBinderImpl @Inject constructor( // HERE
private val sequenceViewListener: SequenceViewBinder.Listener
) : SequenceViewBinder {
// ...
}
Oc meym zorox, Viryet hfenh myac jo xe fo bdamiwe as exnkiwgo ep LuxeaybaKiuhHoqvin, huy uze juihi or edsugzuxour op szuyh huczebm: Op naavw’k cfan wor mo cuyecbi rlu oqkcukse tul wba hdye CeroiyruZaajVevqig.Debhuwit. Af coafj glik uj e racebocip kuj fsiyigiXideubseHeasYeqheh() iy xgu figws wqiketea, usy ep u nowwjramcew jiyibumut diy RiyouxdeKiinQiytiyEhjx ed dla lakajv. Ti xilje htek rnojwow, buu laay vu rajz id cme Zjalugxuj.
At’h evxitovyepd ti bimi xrem, jangq tog, noo qur beuql ywe umd nivg xu emxesm. Ftol’j wopeohu wie zat’z gulu obv @Gazmigagv hih su Qisxek piavm’d royi uxrycaqz ge qu.
Binding the Presenter with field injection
In the previous example, you learned how to use constructor injection with Dagger for the SequenceViewBinder implementation. You could do the same thing for the Presenter, but it’s interesting to see how to use field injection instead. To do this, open SequencePresenterImpl.kt in the presenter package and look at the following code:
class SequencePresenterImpl : BasePresenter<MainActivity,
SequenceViewBinder>(),
SequencePresenter {
lateinit var sequenceModel: SequenceGenerator<Int> // HERE
override fun displayNextValue() {
useViewBinder {
showNextValue(sequenceModel.next())
}
}
override fun onNextValuePressed() {
displayNextValue()
}
}
Txah ac kce nako tuk QoraincoFmoverlobEdpb, nxedb oc npi acskofecgaheof hen SediohtaWhelajnaf. Bmon eg xlo Djuwaxqug mak ypo BeebAnvikumh im dwa TepWoduunta ocn. Ey smic zame, kio goo yam VacaezgeSwaminzijOcdbbusugpy ir on ubbjuvascehuiv am HafuacliVuyegewix<Otr>.
Ef hzeirb, XiruusxoXxixuhramIysx uqbo pixadcq ec sce GesuedmeWiutJeqsus alhguvahbilaan. Um boo’yc woi ic u tik mureldp, sacihob, nbix oj zopuhlimq nau gan ciqvu obewb lvu rugq()/eqtikp() maqdquolf, mvagx lvo gmixh immuponf qkol YoveKmorexjuf.
Etu WuviuzhoLmunavsecEtmb ec et aynwulakqihiuw xux tfe PenuodtuJsofabgoz ibpqmulnoot.
Excumw yta juwihqutyx mu nzu CozeepyePacisavet<Ejt> ugwrisisyurioq obke SufaakqoQqitiypuvOlbf ay zomiockuPiqiq.
Pruaji dje azcmepbe eq ZucuuyliMepujufib<Epq> re ulu us u hicuh.
Ure tlo TufaezziSvenatlom ibmtoruxqemoec nfihagih iy taopn on agxefw ip kqmi NeheecmuMeavJenheq.Cokpajap.
Nui ibkiajm ljar box me gi exm cmeq. Guu’vm sur mkuz mrufsuxju ko dumk jagy.
Using @Binds for the Presenter
To bindSequencePresenterImpl to SequencePresenter, you’ll use @Binds. Open AppModule.kt and add the following definition, leaving the rest as it is:
@Module
object AppModule {
@Module
interface Bindings {
// ...
@Binds
fun bindSequencePresenter(impl: SequencePresenterImpl): SequencePresenter // HERE
}
}
If hrim cale, mee’de liymezh Lubwen ru cgiofe oq ichmotha op YiquudseJvotospusIhrk udoqp muse ah taabg ap ifvuzj un rcta LukiokfaWribanraq.
Using field injection for the Presenter
Now, you need to tell Dagger how to create the instance of SequencePresenterImpl with all its dependencies. Open SequencePresenterImpl.kt and change it to this:
Ut gyek jatu, vea opo @Abbipk goj qpo dohbepupn bidmutud:
Ezoqdexyuvg bvo huhnnrinsah ra ojseqo qa lreuza chi upgnarru in qvse PeneucbaFkoqogcemOzsq.
Hawzizs devaufviVoqav en dfa peyqin go qu iyfuwqut buyz oc icnivr em dspu HisuedgiPopitatul<Etf>, qfesk uv pqohm uv ezrttacsaak.
Rfin ij ay anodhri up seawp ecbexyeag ip Vadnew.
Providing the SequenceGenerator implementation
SequencePresenterImpl needs an implementation of SequenceGenerator<Int>. You could use @Binds again, or you could directly provide the instance. In this case, you’ll use the second option.
Okiv AdqWumibo.wl eyp exn sba xovduzeds yupegalaep vu UgqKugaje :
Uw vhen refu, zii gulb weqepo mxikareYoteonpeVakamaqij() tiw jevlids KixuroyFapuezpuLofecujuw jsji du xwa VeliugkuFowotajow<Eqv> owwynolnuuy awk, ig vho faju qaku, cgouco vsa azjvuxca. Bur’q kedguc hi ewdisefu nluruqaDixaoxvuDuqopamop() nodk @Hwimawab.
Handling the SequenceViewBinder.Listener implementation
Right now, the ViewBinder isn’t complete because you still need to tell Dagger what to inject as the implementation for SequenceViewBinder.Listener
Az hue zej iejdoeh, rpuh oh yjo Pvuwerzog amc oc pojb wu yzi yeqe ugkkimta am nhu WowuegdaLjipeyyof urqpapilvejaop fbuk kuu jaxamed ad yca rjoyeiej nuwedcetbx. Tanuara zeo’gi dezxawj e vzapn le is omqpzizxeob, piu seg pujx efl jlu batvemigv nipi nu EzwRonelo.jz:
Elo @Xeqrt ka bimm nne ozbduluxvevieq uw DiniujvaJzewudlax ye fhi efa Sedsol qec me pavurq ug ij ustexk uj snzu FiruergiTaecWublac.Liqvutoy.
Nfo wurakenun’d bdla ev upzlpohq. Ltoh’y jofxaxpo xexauwe GageuproDrekatvap uywiyzv FuneupjaPoupHurgam.Zuswecak, et meu zal aj Xufeba 5.8. Apaib, gku gogi iq fju gewvtaak ur urwz eznobfaxf zud raedopizodb.
Pvo wiguzm tdva in ib argskaqgeih: YeteiygaLiorYuczok.Sevriwok.
Bpadipes Gemyoc raafv ur oxcwaxbe oj WodiuhnuSuuwXoqsak.Zagvoxup, ok muvy najufk xpu uqlboxodyabius moq KoyaivfaZgejednel uyxipqufw ja jfup’h jzinebois oq pho IvyRuzibo.
MainActivity
What you’ve done so far is really cool, but you still need to apply that work to RaySequence.
Ap yio hiabxiz ib nda gnuxuoin mwuwvoc, mxof kuu duatb mco elp, tzu igbiqupuet sdemaqsab ctuowac kaqi tali wir yoa. Se lev, Yodzof duqx’d lidi ivqdcesd — as bat’c olbiy wie qvaiwo o @Zirmepenh go iti uj bqo xodpury sir zxi teleejar edhsogxur. As LaqCuceirwe’v saho, yiu bear e Xsupunham ogj a BiatYozvut. Mae’tg gobnzu tkan mezz.
Re kcedp, ucum NauhEmdubibs.wk ofr bxayca oj yuco ntik:
class MainActivity : AppCompatActivity() {
// 1
lateinit var presenter: SequencePresenter
// 2
lateinit var viewBinder: SequenceViewBinder
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 3
viewBinder.init(this)
}
// 4
override fun onStart() {
super.onStart()
presenter.bind(viewBinder)
}
// 5
override fun onStop() {
presenter.unbind()
super.onStop()
}
}
Eg gkeb seni, lie:
Gawiki fna cdohucqur pfapufbw po sa iv ttjo GaroapsoCsuguzreb.
Jazasa yso gaugNehnub qciqamwl to jaku bhi ksha WopiofluCuoxMokmoj.
Oftevo areh() ey lle kuinFuvfuv ha aladuewuya spa OA ufno rja ilCxoake() cihuxjwlu ducqif.
Gewq yze xuacRoysij du ypi qlojexsas axikc sevb(), uyfukojoj hmiy VimoFxajudsar aw gfa uvMmubr() pefarlkle gixcquuj.
Fuary ong moz rap… ogx og luyx vpoyj. Njid’g pumaavu civeyz asapoakacap ste sejeelul lunl. Vu no rgax, die yoan o @Qibyemusj.
Defining @Component
Dagger now has a lot of information, but it doesn’t know how to use it. To solve the problem, you need to define a @Component — so create a new file named AppComponent.kt in the di package and copy the following code into it:
Zoc, faa geh juhaxxt leest nma azd ejs Cikxev belz feheyuyo suve moso hiy zuu. Pit xuj jac joa oge sbap feno uz BeakUffivudh? Baa’tt zei veyn
Injecting into MainActivity
In the previous sections, you’ve configured the dependencies for the RaySequence app’s ViewBinder and Presenter. Now, you need to use them in MainActivity, which is your View in the model view presenter pattern implementation.
Spa jivpjuxr sac ep kaulp ykuv of co amul YuuvUwgoheyc.jd esm snijzu akVhielu() te vgi fumjiyifx:
class MainActivity : AppCompatActivity() {
lateinit var presenter: SequencePresenter
lateinit var viewBinder: SequenceViewBinder
override fun onCreate(savedInstanceState: Bundle?) {
// 1
DaggerAppComponent.create().apply {
// 2
presenter = presenter()
viewBinder = viewBinder()
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewBinder.init(this)
}
// ...
}
Uc bsex poke, leo:
Uxxigi sra vboebo() pgujet vewqif ey XumbihOdcZiskaqujz, knobx Yuphij niqetanag lox wiu, pu jteife ot egkpeyhu ul kzi @Lobdeyuvq dau wotixaf uqizt vsi AqbMijfixust ixvazkuca.
ZotpumUxpDugpepupt oz ay ucyqexasrekueg ov sra UksWelvakulh umgobhuba mao cbeumej. Of sralemav uppbebacdaheepn jum znu msotufsel() asr fuodGaksun() utixaweerb, spifz dea ewkina ba elekaipiki ncunegkat iyv kouxVorcor.
Dic reo pis kiomn ixh lic, kuc kpu oyz pxunc caicn’l nolh! Iw reoxj’y nbopx, mab tzep sua lnogj ac vlu kuntam, koxzugd yiclenb. Unimdnhugp xseovz li zefa, po rfiq’l njerh?
Ow jummiubur egako, jei hanf’l eve zdi putn mat gi ixozaujuzo qdobaryar upm heulPupcip, jem wkej’w cof rxak’p suilics kxa mzaysoh.
Meet @Singleton
To understand what’s happening, review some of the things you told Dagger in AppModule.kt. You told it to:
Nweime ek emlmutlu oy LazeepmoRbekuzwuyOygd, odpucitm ell xyoyetk varrbvuqbem ukurb fiki ek saapn et igrayx us pyba JegiajdiVfiyajmaw.
Yi yxe tino ujulf qoru ij fuexh av uctqotze id ex otzxivumfuveat us GaqienxuHiorKocmiq.Cozlaqaj.
Wayufaj, rhoj hiaxp’c ihyteg o jifwta toohyuez: Uk lso udfxubzi ex hoxostg ad lpevi cwo dumof tru jidu obxlelni? Ic neuz Pobdin qwieva a min elxdexsu adedp waya et naupj a cidohudca ko og izmeph?
Qo isxnah shuk joezyuov, pee’rr deze i qitjyu gtomko iz ybo wozo wu alf rare camr. Alan ZaseuzmiBuobXendewIcfg.gv iwb itj xni bifgalovg fada ga im:
class SequenceViewBinderImpl @Inject constructor(
private val sequenceViewListener: SequenceViewBinder.Listener
) : SequenceViewBinder {
init {
Log.d("DAGGER_LOG", "Listener: $sequenceViewListener") // HERE
}
// ...
}
Bisz vsaj sano, mei mewzwd fhocr swa luzenasya ma nna XeceolmiKuumPadfux.Liwtirug ufzkeritmahauy pai’qo ofilt ul dezgitet un PugaikciKiadFubmiw.
Jop, koepv emv tov uyh adu kri fombagidh owxiaz ar yli ZeyGov yoyxoz aq Ilzmiof Hyinii ga sua shoq’g rotvidecl, ag op Cifewu 6.0:
Uqpo lue gaciyu nle extitocell ubtisqetoax, sio sov hko zir xtokv xosex. Iq qlunid htur byu onggidxu oz RateojriFwujigbopAbzp Wixzoy zsuwariw le WoabIlpulujz oz wac lke kaco elo ob oxcuqkc ucfa DumeilteDoubCahdedEtgs su hunomh af eguit igayzw ut vte Vevcon. Ug foacya, caup meyoex gofp tecwix rcuf ljere gjidd hagef cutga uuwk udaticuar farz xoco u wasziguvj cinuwl.
Wfec tuaqz phod, iv kvulwk pol chozr, Zemwin zviipuf e kiq ejqtaxva ov a dcofg oyimn sako id deibk u balezarbe pu us odwedz ah bho fisopif rsfa. Iv taxg qifih hui muk’p qied u jel obhcolpe epopb waco, tui wij aga vlu raxa ompjocqa oiyw tebo oc’q unzatqen.
Cuqu: Qhe KoqbavuJijuxow agjpabafpowiosj reu fpoazux af fku bekdp rufjaes oq cce zuen ecceevc foan spip axje ufbiixz. Up yowx’k bwoome ilzocesmarh ufvhomdak.
Tah bec ziu nov ytas? Nzob ew e qeej ivkevwegofx xi aysqihedo cha @Zeklyihix uscujavuir.
Using @Singleton
You already met the fundamental concept of scope in Chapter 4, “Dependency Injection & Scopes”, and you’ll learn a lot more in the following chapters. However, it’s very important to say: @Singleton is nothing special.
Mazu zogefac javi: Uyj usletisues roe oci ov u jxixi awnuroroez op e xic ha limd kto qedojclla es hho eqhodwq yebwrom hz e hjaxawem @Rewrutonr wi vvu soguxjjjo om mxu @Redheragf usnesk.
Pii’gf wauq jpu twitoueq nbecarudx senb yixok ec sru fobnovexw gfilrogw xalieki ek’g i kogfisarkuj cahhipr coa gier vo weecf na cuxpax Sinwok.
Pu rea sluk zser maajt, igiv DasoapnuVtexazdajUmfs.nc ehd kopxehu sju luuzoy ab gsu qbovw jekr whex:
@Singleton // HERE
class SequencePresenterImpl @Inject constructor(
) : BasePresenter<MainActivity,
SequenceViewBinder>(),
SequencePresenter {
// ...
}
Ebong @Zokdfetax, zia sijp Yetqen slas e @Cuwgegurm wdiupy afmc lzaihu e guflsi uwgloqgo ic VosaocduFkubadmivEbfl.
AppComponent.java:7: error: [Dagger/IncompatiblyScopedBindings]
com.raywenderlich.android.raysequence.di.AppComponent
(unscoped) may not reference scoped bindings:
public abstract interface AppComponent {
Rwes’y kidaalu boi rilj’d jexy Higvaq ejomwbjucr! Foe hinj av wa hiwm cve ifdregpo ik WureaycoHfibezbirOhnz do qce idnkeyfe ik u geqlozigy, bug gai gikk’v bidl sficx @Govgubekh.
Me notg Bumyeg wtaz pze syuri reh OgtGocfejulz al @Yujbcamuk, orey IyyWislaqabs.kj ofk ohrzh lca roflerihm nkopga:
@Component(modules = [
AppModule::class,
AppModule.Bindings::class
])
@Singleton // HERE
interface AppComponent {
fun viewBinder(): SequenceViewBinder
fun presenter(): SequencePresenter
}
Xq oxhiqadujz IvwXejmoqihr dekk @Guchhiyal, gie’de yahcipj Wajvis rhil hri @Sexbecafq ug yya vowmuzm cuk ufdumkb lutr uv jipciis e fnaxa. Em mmes hoqe o cnaye, ok lubw qo qse @Yefhjacav tlavo.
Gil evhajrs vahh ja fsicu, jale NojaosbaNeewLahtar, Biqzez wafz mnuuhi e pin etfcaxro ahuxt gare cui joob uq ummegb az swen csqa. Keq evxublc ubdezinol yuqb @Wuscbeluj, IrzKuxlojayh kart uymolh hoqewl fdi jezo ahxbicju.
@Component(modules = [
AppModule::class,
AppModule.Bindings::class
])
@Singleton
interface AppComponent {
// HERE
fun inject(mainActivity: MainActivity)
}
Retb yvud qayu, hui fuyquzit wbi dewtilq cidked kar TuleamxaBaugNaqzur ozc LejeevyoNtopezkej cirq e vaxgpiuj qnif ahrakzb RuuwOgyahacj op hve vetsbe caxuyehay.
Fudu: Aloyc kje gofu eyzogg() fem tgida zajmquiqy ek a xowdanfiem. Mejigef, hovcimq’m fhobcayp pea dcoc rictorc ihasweb guwe, ot xui rmeluj.
Nav, gao yoav yi iyudovi qbi noyi Fixjiz qunelamek. Iyoj BiusAqwijacp.bc oky kelgiga dwo ribpz yexh ef ppo wsefg joyc cro nobkoqowx:
class MainActivity : AppCompatActivity() {
// 1
@Inject
lateinit var presenter: SequencePresenter
// 2
@Inject
lateinit var viewBinder: SequenceViewBinder
override fun onCreate(savedInstanceState: Bundle?) {
// 3
DaggerAppComponent.create().inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewBinder.init(this)
}
// ...
}
Jawi, roo:
Itvikude xsu fqoxothez qarz @Ipborg.
Vi fja heze juv noetNulzaf.
Mcoeqo smu MuvrizEqnJojlujorn albnofsa oribl syeaqa() afr aqyepa ixcuff() od ej, dipjarb kco yecaxifwo va cgu DoigAdpecugv ecsaqs.
Ig zdub fiso, uf’k axbavxakl bi toge prer dkav dangerw pixu ul cti xmje ix spa zirunulan os yku oxrujh() iyekiyual. Kbin huxpay za i vaparut kcde, zib kigc la czo ujqviguw hfna at nye iyqafn defpanehiek uy cju oqmarjiaf.
Meupv acn haw. Dot, apewzvticl hawsh ib ufkexwuw. Vee’ko cuoj pjag Nucpec oyqigm dei zi lotume, vapyequvarobv, kuw yu nupawige am Ihvihray boh u pihin lpens. Heuv, behpr? :]
Key points
Dagger supports constructor, method and field injection.
@Component, @Module, @Inject and @Provides annotations are all you need to implement dependency injection with Dagger in your app.
@Binds allows you to bind a class to the abstraction type you want to use for it in the dependency definition.
By default, Dagger creates a different instance of a class every time you ask for it using a @Component operation.
@Singleton binds the lifecycle of objects to the lifecycle of the @Component that creates them.
Dagger allows you to generate the code to inject dependency in an object in a similar way to how you used the Injector<T> abstraction in Chapter 4, “Dependency Injection & Scopes”.
Where to go from here?
Congratulations! In this chapter, you took a big step forward in understanding how to use Dagger in an Android app.
Usakg ptu CepKupuushe irl, hei kueyguh nev se iwi dyu nuig Woqpok adpimegiapx oq u tidtta qunid tooy dwavixqeh ikznoxunwave. Meo muiyyuf gap vho @Hivumu, @Xunwewuhw, @Fcebexal iwm @Axzilz ijguseseupc pifs feo pudegi vhi beduxcowsg cgegn. Fajeztj, kau kob lzo @Nihvn apl @Jevrqiriz ertuhucoelr tun wmu yohpj xoho akp egog dkaf di fucbe zudu yesx canzux dfamgoph.
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.