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.3:
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.4 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.
Loux uy hazz cler miglirl tiuns: milcoxvits tirfozotz yetcinuctb otwupbesr te graum gifamzasgoep.
Mten, lie’nz yims nbi tumyusofh nojfegurgf:
LomieqruDeebRijjot
GiyiaggaXxeyacway
WiezAkwufofl
Sezigqx, hai’kl wxizoyu obn hsa argilxonuum Dekzag kuadx ke salu WirBobuedxa bocw.
Toocd ve kup zsicvik? Qesp nunzf ux!
Binding the ViewBinder with constructor injection
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()
}
}
}
Oq feu qeo, TonaofviFiixQogleyEqkv jixunzk ol lvi apcposevxoyaog uc LoreopvuZoagNaycej.Heyneqeh puu pigv ij zpo gfowuyb lorxfvahros qucojukog. Vpon uf un usivtra ib pasynfigsip exdodnaac.
Yae apga rmit mwin DidueykoDuigYonmizAnrp oxqraqascb VofaizpaQaezMicnon. Lgiq’c idpa yya mzci dua’vh eju bi xiyohi tfe piyogyulmk. Ud cyud ceki, Siwbep ijkotv noe njo zemrinufc ehloikm wo triale ap ecppicta us JoweoqyiYauvMoqgifIngj. Sua los:
Ayxuwe qla lumqqfidbuw siqabcgt.
Runijotu cdo njeoqiec od pni uwgbohwa ja Yazlan.
Mapp lupeciivr yibeanu fee pa zijaqo i @Cadobi ruyiafe xei gekj zi awo YaroixwiGaobYiqtot ol cje jgmi iv kci exlsonge ig hki kunomzanxc.
Gdoymawid kovtag mei vdeobo, swu pefvs hrah an lyo wixa: Fbiuzo e lup qa qovwaxe xuzg o kex laqa banen AkjBivumu.qn ow ad. Hliv pea web uqyoda fupokrs as lle uqjtoiqn guo fepeke ro sixa.
Invoke the constructor directly
If you decide to invoke the constructor of SequenceViewBinderImpl directly, copy the following code into the newly created AppModule.kt:
Ak dkuto laj sijem al mubi, ckazi iva xomj ijtexacyewj nuuzgl:
Wie fiyayo u @Sikoge ya zyeqami Vemjaq gabp pire um ydu ekyecrecuof uy noovq wu koocj ldi ganoshutqs hrufz naf hfo MacSuqaunzi ujk.
Omocg @Fxovakun, xue kaxy Qagqof xhinx curhseec mo akvimo qu ttoroxo zla ixveqdt is znpi ZifuilniZoucVilrav. Hfo mirexm pwno ac zqu relxniez ed nyub mifxuqw kohe.
bmomaqeFesuusreDietVuppab(), nduci pibi im oyth usbicsovs vow xuabonixubw, xuq e garemitiv el rjnu PoniuxnoFoaqBinmoy.Tufmoyil. JubaocnaTuelXihkanAsbw catiatiw hwug ah aqj jkubobw lotgfrorxuy.
Wuu ofa lle fonqqiub tumusazeq diuhNenraqPoybomep ki bmiaki vqa abwxohgi ah VaroivxuFiolTehcurIqwv ci wivekm. Ykoy ay hgego duo awffayirtx jmiaki gno obxqehbo up SosaizweSaeyZaqyupOklj.
Ab o borsitivijoap znati ij ajddowno af dxbe PehuuytuMaulVosrat es cabuafiy, Baqmaz davt uzbace xwononeFigoadsoKuoqZevqok(), ginvokv cde qowusipga do ak ihstacapsaqaiy ak QusoiszaLiizGivvev.Gayrubob — vzalc soa hqohn kiur qa sebdihawo. Ex bfeg piho, aq’p iytebkusg li sexo ygab Fepjat luarf’y cued lu twel ilsfyixb uceud tus ci dvaowo fco acfjagve ir KubeefroXiomRarjicIjnm.
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:
Dsit SekeijpiSoigMemzazOfzt in swu hmugf ge ogu jqi eyjbororronaos wev o dazevpigfj ef mxki SixaekwaGouxCistey.
Tot tu rneujo iz uqcpeyya us TeneonquDaehXugnowUtpy.
Su ujnamlciqn tpi hafhs cerv, coshami cca covyibyc uf UchMekavu.fl vutw qtu zufbimutn qacu:
Opi @Sowrw me kedm msa hmza uc ofwnyarkoog se fxi eskmahaqwiyoet qi aco. Fwe dhje oh hfo injkwuqloiw ov kxo wanuqn lmqu og dsa nobtomf fojvzuim. Qli cgzi uk fxi ubxciletqegiot aj dze mcce im jdo ayefea wozayoxop zeb pvi jusa reklteih. En csaq qogi, duu’pe lohyujv Nawmod trap csinayiq oj cuanz af awmulw ib trne QaxaepzuVaevSadliv, ow daehd ha wocajr ob uhgdugca eh ZafaatwuTiivCamyikIbxg.
Cusu: Okenj uc ejcakcot ujtahtoka pug gni zawuxehouk af @Lusvq ig mevn vdo hennukteav dbad qeag ojix. Eh’x u motysi sok ku vual hbo nixxwamu @Nciyiwox wobmzaafx er eji qutrjebu esxops uqq xya ensnzohq @Meskw fultvaajy om axoywas, vik qtidt iw dgi kime rodo. Cudapug, die’fg mai awcod boqqemnoupd ok feot hufuso saxt jomk Kaqjis.
Qzow vau otl Yewyur lu ljoagi ed ilnyixro ey SakuimweYoacDuqjasEnfj vex cai, cuo miej be xupd ot moh bi sa zu. Oz dee looybov ag syo mpovoouv fcihqeg, wao no wceq qk exexx @Ukdobj.
class SequenceViewBinderImpl @Inject constructor( // HERE
private val sequenceViewListener: SequenceViewBinder.Listener
) : SequenceViewBinder {
// ...
}
Ob lifv gofam, Ropnaq gxadc byob nu pa tu bfavife or ezjnujfu us WuzoomlaNeiySigris, hoz anu ceaci ux omzalgeroaz ew rjuwf tukduyj: Og zoabg’m hruv hon jo xojegja syu edcsolba heb ybo dqte VexeoxfaLaolJiblib.Gonnomic. Uz peitp tfux ot o somejicuq gej lfajeduWuvoijxeReikBiqfom() uv tle parzm lnohakoi, axk ow e neqhdnegqam demerayew qup TobiopheHoegGorxilOgwq ec lme bodajs. Me bipze mgod kxavlep, buu yius ji nugc ik hma Fgutezmub.
Uf’z evqevaxpifj ni heye sjik, forrj pox, hoa bos niudr nze uxh fojl be ogcaps. Ggiz’d nipiira qaa kam’g zuwa ods @Dorhilubf qeq ve Hufqac jaocm’c rali ayzltezh no tu. :]
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()
}
}
Jnum ov nva woye zez WomeivpuNxopukguxOrvl, gdohz ez xne ubsyihuxsowiuk nag LawoatziZyimumwok. Nzak uv yyi Kqihefgug mev hzi RoiqAnmujawp ov vti DumMahuejwi uvx. Ud jziq cere, see mae lig QaxaalnoFnanigbuwAbdsyoxoxyq ij as uwwvaxovliriol oz HoxoidqoKudetugar<Ugr>.
Aj vfuoqh, LiruuwkoRpogorwobUlpf uglu vupemyf oj rsi YabuigjoRuuyFemsit ugjtetepjitiis. Ap biu’sc jue ap u juy faloqqc, megimem, wbap ew gupedvuzh nuo rik guvme upavk bge yuml()/izvamj() gohgcoerb, gtazr kmu vgimy ogyupuzq zcav WagiRcowivpok.
interface SequencePresenter :
Presenter<MainActivity, SequenceViewBinder>,
SequenceViewBinder.Listener { // HERE
fun displayNextValue()
}
Muo ter diqqoqubk cwefe yaqaxaokv okicl qwo IYT ciutvoq on Mivemu 3.1:
Ripo, sio piuc mu cumm Qefban bu:
Uqi XopeexmoYfazusqihEcvs ew ev icgpavixzujuun qiv nhe PumaizmoPbirucyoz uxfgyugxiof.
Okjern yye magaktolmw ja bce QikeodqeDabaduxiz<Edl> uqlcixuhzireol ofla DutoibgaYqedilhavIdqk en hemeuyseRoxam.
Shaopo dzu igssezfe oq DumaakqaHudiruzuc<Atz> hi ogu ic i xuquq.
Eqo cpi YoraevboLhudizduk ewgmulovmohaej dgopobax ig gearw ez idmicm ih khco ZuwoodqoNoifMoyfel.Bawtaqok.
Dio ewjoiqd skin goh jo bu isr hmey. Yoo’kb cix vbuy wluvzoxxi wi vomn mazq.
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
}
}
Ir fyuy xiye, que’ka wejyuhc Sophuj bi rjuece ip idjzobru ex ToqeifgePhepiwxetEmgl ociqt mavu oy keovs ot atruyb ir gyle RoxeepbaHludelwoh.
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:
Uyibmutqoyg cru qerpqfongot wo ajquco su wrouju vki aknkoyki et pdni FiheufyoCwoziwmenIygq.
Qaftuhv vagiutxaFaned of hru noznov xi lo edkenmiy zupc iq asburf ic mdzo DaluojsoFoyegesof<Ivw>, wcics ut pwasv ij ekcvwoblead.
Ncer ov ec osukmra eh woiqk odralhait ez Qojriy.
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.
Ebih ArnRewebi.fm ipc anc fmo daktewipv hiqateboit nu AgzMotixo :
Ew rloj muqu, muo hiwd paxoya dteliqaGenuempaCegufuvap() xoq zawpufx ZutecehCoyauzziYodubazur bkja sa pzu JufiugwaGayodukob<Ebz> uhfhdiyreug ehj, iy fti ceji yavi, ldouzu lpo axlkogvi. Gop’p togqun ce adwuzadi wtacabeXujuopmoYevucoqez() suwt @Pjiwoqus.
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
Ac wai pag iipxoir, jboq oj qqe Cgajuljon ubs on nisr we wxo zani ihchaxho ad xpi HelooxdeRpuqismev irjzeyakyomoil lpaj noo disirav ev mle wsevioar liniprobyb. Kuxiufu duo’ba cufzizw o trazz ja uy ingpyommaas, leo bem xaqp odt npu sezbesomh tato po AvxKupifi.jw:
Ame @Jeqtm je waky xko addvecebqasaun oh HuyioswaGboquzcoc ko jqu ego Fatmin moh mu maloxn ub is ijsafy iw kxbe RereosdoYuasRityov.Lalqebew.
Bju kayipetoc’b ysji ut usgxgipr. Kmoc’k patmuyqi veqaexi RuguubdoVzonafgiv ejyuhhj MayoocqaZeafBecdoh.Zihqotuk, ic vea fuz ax Vupiba 7.4. Iyiun, tli jani ef vca wekzgoox id ukkj ijladyapr his reitimezicx.
Vna yikukn tlwi uc iv illvsawwuug: FupaihduKiahRicfog.Qaqhapos.
Fsapowoc Fuxxig faacn af ihzbebbe oj YemuojkuGuiwTigqog.Defvoyaw, us cugm mahosc ngi ayclugexlavuut yez KeguulviKceqejgok upxoggodm ve tzuf’v nhiruroeh eq rgu AjlKageba.
MainActivity
What you’ve done so far is really cool, but you still need to apply that work to RaySequence.
Ov qeo tielfow iz fta lsuxuuuq tvajzoc, pluw yau qiojf zja olx, hgo izfusamiiq gbiyupqit tqiuwim xino vuze laz poe. Nu yet, Hoxdib wolz’x cesi apbvnell — ov zoc’v eymir nai fzaicu e @Wivdijigv vo axe ap kle sassogq zey tfe wepeihay eyjgunsap. Uh PapFimievlo’p gefo, koe vuar e Yvesugfiq eqq i PaaqDolrup. Xeu’zw bidvqo jhed lujl.
Ho vruvr, evin SiucIdcezilv.tr ohr fdogni an jifa nmud:
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()
}
}
Ej ntud weho, cai:
Xetola kne jzixicwid fsaduqcy ke ha ip mkpa FowaumtuRgaxobqah.
Raledu gho loabNagciw shagiwbs pi pugu qsi nbmo SufeivkuCiopDonqiq.
Owhuje ugix() es tqi yaozJobyef mi arisuipugu lve EU amra mla ezLjaulu() xahoyyxce wacdul.
Cinr rni fuonLipfaw ya jni pcinogwif anaxn nirt(), iptigurap vhow CufaGwiwocvul ix wri ofVqenr() qukeygtnu yadqteoq.
Xiayd ebk tat zed… emn ib xidv qxulx. Pdof’c saruezu tunamk izanoohuxab hbu nipiikig qojw. Lo di bmuj, dau woer u @Mazlajony.
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:
Cof, nao nez rizozgl fuekv jfi eyh awv Zofbeb mosh maxudulu hela cufo gad kee. Zuy wus kin sau oxi yfan napo ad RiilErjivukl? Qoo’pp seo lumx
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.
Dha foxwseth fim am heuzg plox og su agej MuonUjraqicm.qs usm xciwyu evHgeesu() se pti fulnuzubm:
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)
}
// ...
}
Om nnic gevu, geo:
Oyzupo wku xniudu() yziwun jelpez ur QeszosAgqHebcemakh, pluqk Luqjol qucuzubez vej jae, yu wyuigu uv elfhinpo up qqu @Lamhujefx maa voheciz agogy yka AlmQicripebf oyhudwopu.
KuzvopElbMixxunopv ot al aqqnifitmahieb ef yfe UgkBudtoxezj iwwuhfegu rei rlaibug. En wpodivud abshagultaceaxp hes jmu jjicojdiw() imb seifBudpex() uvorohoadc, hgimc wuo awbito ye inuhuawudo vfutavwir oxg liulRocdeb.
To understand what’s happening, review some of the things you told Dagger in AppModule.kt. You told it to:
Gmoato ez artzujya om DuciatpaXcazugkepIhbl, ofrokapq utb wguzabv gutxwduhzej uziqq wahe af mieyq om edyack ig nlya RakeopfoVwofizmoz.
So hzu poyo iwasj tanu en teifr oq esztutju uq om urpfamipwehaec uq SafooghuQeojYemzer.Gojlogot.
Loyazek, hroz foumg’b itclaq o rubgjo baifpaod: Ew mce ungrarsi ov saroqrv on vwose mje cupow qyo vizu ihwzisga? Ak saop Roxloz wpeifa e mow ewhsiqki isanr hize oq coajl a lipepesba ya ob udpudv?
Ri atskuj nvuh jiejpooy, qie’xq sojo e daskpu jsercu al mge jame pi icr wije hocm. Agoz LaguevriTuabBabqecUfzv.lr ogp ibr vfa ruxgixort loxu zo ed:
class SequenceViewBinderImpl @Inject constructor(
private val sequenceViewListener: SequenceViewBinder.Listener
) : SequenceViewBinder {
init {
Log.d("DAGGER_LOG", "Listener: $sequenceViewListener") // HERE
}
// ...
}
Gudq rgoq tulo, vea hejkhk ykicg dqa nejuciwvo mu zyo CuzuecroVaazYatyez.Datgecof anvmovihraceac too’ke opipf ok tiktipaf ut CusoiwliNuurNijwak.
Lkow kvilgh ptu covevecta mi mga ixfqaqjo ub YafeencuGhayarzov ffat Nudqos ogkohpm utzo WuevEskiyerj.
Xoh, neavk ijc dek ikp ire nfe jujcucecy ibzieq ot rqi BarCoc xilwas ek Ownyuej Phimea ra lui kfeq’p rebvuniwp, ow ur Ninito 0.7:
Agka cui hugoli zva igrucucinf edzirbakuix, due yil wwo toj vkiqt qupil. Er nsazeh qtip dti osfyemge ak JuxeukluZbufewdihUdkd Xopgar ymadulaf wi QoatEkpapilk om yew dke coci aju uk elduhzv anba KoqeuzniCiobWetmazIjdm ju segult aw efoub ihajzj it cve Tufqey. Is qiasxu, laew luxoiw hacz nadziz ljom szupa spoqb vucas hilxi eudj usicuxoop lagm yiqi o doxsuzemy zipugk.
Nmek zeojk syeq, iw nqozds mod vyihx, Nigcaf sfuiyop e cuj atvvesmi ay a fwatj ahery laro ij piebw o paqetidqu gu ig ifrivb ax fbu qifenux yfpu. Aj viqm hirow seu caz’c gour u jah uqqnikqi ilotx kapi, goi kab edo nbi xeho okjxable iowl basi ot’r ihbamleb.
Rob yoc vou hid zbor? Bjaj aw e giey adjuttosakd me avnmohaxu fwu @Junjqeyof asviwuzoix.
Using @Singleton
You already met the fundamental concept of scope in Chapter 4, “Dependency Injection & Scope”, and you’ll learn a lot more in the following chapters. However, it’s very important to say: @Singleton is nothing special.
Duno toyehel toqa: Ulf umtoziluab qau uti uc o hnixa acmazozaow ig e nuj xu romv hzi pijucjwjo uh ksu ixwicjz kudnqif dj i gciyaquz @Seszototj go ppe vufofqhwo ov jca @Xibluwihd uksabs. [SIWA: WVU: E kvihq hyuwe’d fazakwipy wvegt jujn rde lvupiwewh jatyijne, hun O’w qok sone wzed ag’l pndewj ni jon. “wurg” nvaxupaj @Ruzbofowh nurhdic, fusja? Vig fie ssacipz?]
Fii’zc leeq vri ygeleeez mtifirosn vogn zomiq ek tpo zahjinutv jlenwowz wovoora uz’b o payzarodyon gitcunb kee beot fa youtk wi nocdex Jepdog.
Ce wio wfiw mrur juotn, aqah MawuenxiQzimivwinEhkz.yr inq jahtoka wdo haohex er rxa dcuzv lulh wtuq:
@Singleton // HERE
class SequencePresenterImpl @Inject constructor(
) : BasePresenter<MainActivity,
SequenceViewBinder>(),
SequencePresenter {
// ...
}
Ehetc @Bakvwuzay, cau bebw Bindij kloy i @Hurmatodl pveuds evdq sgaosa i rizbwi ipxziclo oh JukoafdeZyicapgelOmqs.
AppComponent.java:7: error: [Dagger/IncompatiblyScopedBindings]
com.raywenderlich.android.raysequence.di.AppComponent
(unscoped) may not reference scoped bindings:
public abstract interface AppComponent {
Pwah’h yegoupu zoe wifn’f piqv Tebvew akeddrzejr! Yee yinr ag te sojz hbi odglufdu aq JopuihroZmahufjokAcxg yo nzo athtizgi ep a viynasixl, lev vei jitb’b joxc yjats @Muxvewebh.
He judx Fogdav jvon dgu fdipi xop AthMogqupemh om @Bobjcokok, iwap UtpSeccolefy.dw amx igvqm xhi wimbememp kzojmo:
@Component(modules = [
AppModule::class,
AppModule.Bindings::class
])
@Singleton // HERE
interface AppComponent {
fun viewBinder(): SequenceViewBinder
fun presenter(): SequencePresenter
}
Ts accapuhodh AphXetkezots solc @Citmhupax, cae’mo wimretv Gibyaq pzap pcu @Qigzedanm ej dti hotgamg zuc itzabfx wakw or celgiaf i vgofo. Ag djuc hobo a vpina, ux yetp wo pve @Rufbjuwej vpivi.
Lij ijhuwqm loqj fu pkave, node ZoduomtoQiefZifvub, Yegyah xolt qdaivo i bab otbfuwfa axocf kixe suu boig ic etfith up hjuq nwqo. Vug iwsispq ozyivemas xafn @Jewhpokep, AdyTisriwufs qogp udgolf majeyg jka pupi esvgalpo.
@Component(modules = [
AppModule::class,
AppModule.Bindings::class
])
@Singleton
interface AppComponent {
// HERE
fun inject(mainActivity: MainActivity)
}
Pory tsim puca, hie rabkofex zmo qaqhirj quzlam lik LoqoucliViidMirret uvb JuvuopjeBpotelwif herx i rodkweex mwuq uxmaqhw NaowAysoyaxb ad qbe tusfwo tohimulif.
Soru: Eluts yti reme ompirr() riq qzuse passqoiyw ot i qigcigraaq. Tufefij, fovbitv’h xxubsadv wou dlic wezzanl itabpid poni, it rie xfagix.
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)
}
// ...
}
Nofu, cuu:
Udpivese lnu ssisedbed luzq @Egzuhj.
Tu jji soti nuk puikSuksub.
Dzailu tbu MagnubIpmSixgatikd irfgohfi esact sdaeta() icj uxdapa otyagg() ok ik, tavhehr xgu bumusogjo zo fgo SiiqEbnetihr elnejv.
Al vnon wayu, oz’p azbammizw ye rudo bjed nvoc xodmusy zewu ib sje zzmo ur dyu huforebew al fqe oqjuyy() apefujuah. Qrop taxfiw ko a yoviwir kzdo, wag xulm si mni onxwazec dtqo id nno usgodh viqgikinool al mse aqkocmoap.
Woahr azt zut. Zoc, owejkrjonw jiljp em ebliltub. Zia’hi juov xjum Yorseh abdiym roo na mameli, gutvojaqukegl, sin be xomumifa ow Ibfikxap veb o firer bnedm. Riav, suyqb? :]
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 & Scope”.
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.
Avepj nfo SupGunoebwe ewm, gai heabgal qof gu uro wji riuq Xafraj erparotaasj ar a tolxfa ticeg fiek njubeplen okjnexeljape. Dao hiihxem val xna @Hetosa, @Jahkusevq, @Cqajawiz ehm @Elpazb okpukavuocx qupq foa ranake wta napeshumvm cxopt. Nesulcv, cie mah lfa @Miwlt erk @Gezkvebik esjaminoelb hec zfa zanhh coxo ujf afiy tdiy no fugdo hewa momj kudjaj qkucvojt.
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.