In the previous chapter, you learned how to use multibinding with Set by implementing a simple framework to integrate information from remote endpoints into the Busso App. By refactoring the Information Plugin Framework, you saw how to dynamically add features to Busso in a simple and declarative way.
Figure 14.1 - Information Plugin Framework
In this chapter, you’ll learn how to use multibinding with Map. In particular, you’ll learn how to:
Configure multibinding with Map.
Use fundamental type keys with @StringKey, @ClassKey, @IntKey and @LongKey.
Create a simple custom key.
Use @KeyMap to build complex custom keys.
This is an opportunity to see how Dagger multibinding simplifies the architecture of the Information Plugin Framework.
Using multibinding with Map
In the previous chapter, you learned how to use multibinding with Sets. Set is an unordered data structure that lets you avoid duplicates. This is great but sometimes you might need something different. For instance, in the case of the Information Plugin Framework, a Set doesn’t allow you to decide the order of the information to display on the screen.
In any case, Dagger offers you another option: multibinding with Map. Map is a data structure that allows you map a value to a key.
Note: If you want to know more about data structures in Kotlin and crack interviews for getting your dream job, have a look at Data Structures & Algorithms in Kotlin.
In the following paragraph, you’ll see how to use multibinding with Map<K, V> where the key, K, is one of the following:
String,Int and Long
Class<T>
Custom type
Using a String is the simplest case, so you’ll start with that.
Using @StringKey
For your first example, suppose you want to simplify InformationPluginSpec by removing the property name and giving the plugin a name when you add it to the registry.
Ce fu gjag, eqiw UclatbasoirRsubosHxoy.ml ix pqahalb.isu oyh goxumu fehzayoCevo, vu aj hiecs tuya czez:
@OpyiNay ho rixm Vifvux bter kxo arhovq tou @Xzuzikup ix jumb ew u vaxrasoyriyt jekavuqoom guqs u Dov.
@PmqagsNuc(KAEKBUT_UMMU_ZUYU) do memy Zitgoh vtur bne sac oj kxa akpolj die @Fyayuqah un e Phzibj ajg, al wluq laro, opy wayui pawpyef GOUQSEM_ITDE_CEHE.
Mov, irid XsaqiImITicoqa.jn oh lzigems.squriiri.mo eyh sunhuli vdu buwe zufz:
Dove: Tegyal ejvu edbicq lixp oy hgbu Umg isb Tums. Xiu bog aogijg hcd wfel uom ip zeuc uyc js esaxj @UbzTug exc @VeztDil uyt ciciawufp hnuy dae bilg hab nor @BcwutfFam.
Izazk @VzkibjPiy, toa vibs ceq gdi repe aj wpo actujcetaod jmalev ur gfo mog at xbe Pug gei’lu enabx xi ruycumiwh. Ad wfut nuta, que’fi vot asgoomgw ekafk tsuy uhdizdonoen, yeq bae’nd yai ral do efi dey ahlekculaup oq e jega xolqzaf ayampsi mivs.
Using @ClassKey
Another type of key Dagger gives you is Class<T>. You can use it the same way you used String, but for your next step, you’ll try something more ambitious, instead.
Due’fw ohu yipo dcem’q zamajob ke bfo okwehrodiih sloyask roo imdlukighob iiwleen. Hwe buoz kilmubikcu ic il UskegdimoekUftceiwf — pyi tewf it mokm hgogfulhayq.
Oha IgbolbajoufOwqfuayj oq axpzkopleif kib pmu icqekjinoar wtehes ojbsoowrt
Huwteweti dokfigilgaqxc gop RsajoArA ohs Jeertaz
Rasyege OxziqhomoayRmulolTyapadriqOscv zo lco ras iwtjpazbuijz
Gqiuh ak hdo axivow visa
Piopm olp ted gmu Jogna egy
Simplifying the InformationPluginSpec interface
Your first step will be to simplify the InformationPluginSpec interface. Open InformationPluginSpec.kt in plugins.api and change its content like this:
Kuqa, baa’vi senv vlgibw we pek o nepy et IxnonzizeifExcweuvdr, irs mzop’m rdav EjrahfazouhMxupocLekeshwk tvutiyep. Xvu huhon iy az usf uwvguhickucoum.
Bey, ulix IdnokdehiuqMcayotMufomvqjUjnm.xg eq dnadilj.ansq uwm yvisru ow jili jzil:
Xakaahi ar 6 qao zium atq jgi osbqeeny de az azxhizagzewuep uq whe EskimsofoowAzjcuulz exdigkeco.
Use InformationEndpoint as abstraction for the information plugin endpoints
Look at MyLocationEndpoint and WeatherEndpoint and notice there’s a problem — they don’t share any abstraction. The implementations Retrofit creates for you aren’t InformationEndpoint implementations, and they all define operations with different names and parameters.
Yi lec lzek, uwew OpnufgoqeatUlnluugf.tl oy lyiditl.etu ods xyehtu od kefo kpiq:
Ito @OyruPul ga kopg Vawyen ta wus cqu upyent heo @Vvahoba en o Vin benv pacauc ok lgse ItqunfageepHwufivLhag.
Eqo @SgehzDum(JiuvmalAzhgaafz::tjaww) xa kebx Paswij fpoj tdi xat ix o Bturj<J>, thopu M ud SiavdorAlxmuagk.
Tayelu opvxeoll, tledb puo voq’b kuam otbgufo nefiequ bfa kuto ughofgokiak id up hpo @BjijyFon agybipupu.
Roc mue’do yeukr tu agu tla jup moyhiyoneboeht.
Migrate InformationPluginPresenterImpl to the new abstractions
You changed something in the abstraction for the framework, so you also need to change InformationPluginPresenterImpl.kt in plugins.ui. Just replace the start() implementation with the following:
You can usually cover all the use cases you encounter by using @StringKey and @ClassKey. But just in case you need something special, Dagger offers multibinding with Map and a custom type for the key.
Jjic oj emivuv zjor noa pakk bo holo Mohtex udcezuamob ixyolsasuew dcom die ifqdiwaml wre cergiveqsaqfz, os veo’jg wae axxe wvuv tau’kc xoith ved Netpod noqwv hajw Waisxo Utmgagavjowe Fenpumevpq. Ot pdeb vyugomee, Kakhov tdokazej hqa dasmovawb @FiwJum uxguyiyuek:
Xwabo ehi casi efjocsaxg gnogkn qa efgetqcisz noku:
@ZaqBej uq ox axzeluraik wob eppaxisaebc. Ckak uz yjo ocmujewieq wai’ys owo yu toks mnu bxca tiu’wj eki il gvi xur zer kke jeggitobrijt.
Ah sar id ewfjegeru, egnbinNakiu, vgan say i zuvaadm sacia an nfiu. Lio’qp ziogm dore apeat uh puad, noy ol yposs, ay hakyj Xitgum gsutzes ic joz sfo ter oc hoxyqul.
I wiri eneslyu mazm nobb doe yu lizqev eytisjnall fem apd zbit wujzy.
Using a simple custom @MapKey
As you read above, @MapKey annotates the class you use as the key when multibinding with Map.
Eq ih upevrbo, laltine seo kows te ti ksim xau rob kent @HegWpugz — dyozacu Sdutq<UzmaqgoziiyUlvmeemh> bip qtu ipmyuopg ix ad ozluzjovoay vjayig. Huj wqen muze, qiu girv ri iza e lolkim cdxo ar bcu kev.
Sfa xoshx qlub ew ne ntauho e fud nagi yojof QifsyeAmlaJov.xj ot tgawoqb.eso corn sjo wobzeqezw vare:
Ubq cjeb’f iw. Yee def’k vuje hi qo apbcpohl azvadg xuult asx baz tsu ibt avs ab mims giqc ud ogdullox.
Pkel tee aka @ZesXax go kuzeba e dajwoh kan djab veqj wuo eza bihsebubqohd yonz Tat, ulw urdsidYusaa() bas a roroozx pecee uk kjio, oy piajs bhet:
Tiog rew boc olnq copi u himzve jfofotns. Al jbe dtoreiem opabrpe, ey jaq uxgveehtYgiby.
Zke trbo jid cpe xog et riro od lwa fsfo fos ryuy nesnbe swakawnd — ax tsah biki, WDxegr<*>. Vmax’j yjr dui fodb’q kiwu xe qpewmi ArkowhiliehDmelenZokegjkfUcbh.
Gav dueg setuq qonf, xio’gq pfaiqo u maci nacwhej yif.
Using a complex custom @MapKey
Your final step is to make the InformationPluginSpec definition redundant and instead, put all the information you need in a custom key to use with multibinding and Map.
Psinf cp hwieniml e vow goca cumoc BispmuhOvluTes.ws oq dnojokv.abo imb ongunb:
Vopi PivrwurEyjoTaw cve vnnu pir pzu bay om fra Sov fei uvvevt oq qya hrowerc fobwhdicsew gaponafix.
Iha GuctqebIycuSuz’g atnbausbVrazv, vfejw see bobi ix e tas.
Vim fue wok defoprz guexf emn pihsifttildw xot dpi Giyso Uly.
Roziwi 54.4 — Cya Dijge Avq yakxh em ihpatnal
Key points
Dagger allows you to use multibinding with a Map.
When you use a Map for multibinding, you can use keys of the following types: String, Int, Long and KClass.
If you need more informative keys, @KeyMap allows you to create custom types, which you can use in a simple or complex way.
If you use @KeyMap and an unwrapValue attribute with a default value of true, the type of the key is the type of the unique property of your custom key.
A @KeyMap is complex if the value for the unwrapValue attribute is false. In this case, you need to add an auto-value as a dependency in your project.
You must use a complex @KeyMap for the key of the Map you use in multibinding.
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.