Dagger and Hilt are libraries in continuous evolution. Google and Square, with the help of the open-source community, keep improving them, both by creating new features and by improving the performance of the existing ones.
One of Dagger’s new improvements is assisted injection, which Google added in version 2.31. In this appendix, you’ll learn:
What assisted injection is.
How to implement it with @Assisted, @AssistedInject and @AssistedFactory.
To do this, you’ll work on the RandomFunNumber app.
What is assisted injection?
In this book, you learned all about dependency injection. You saw several examples of how dependency injection can improve the maintainability and testability of your code. You also learned that constructor injection is the best type of injection because it allows you to provide dependencies at the exact moment you create an instance of an object.
It’s not unusual to see code like this:
class MyService @Inject constructor( // 1
private val dep1: Dependency1, // 2
private val dep2: Dependency2, // 2
private val dep3: Dependency3 // 2
) : Service
Here, you define:
MyService as an implementation of the Service interface, and you annotate its primary constructor with @Inject. This tells Dagger how to create an instance of MyService to use anywhere you need an object of type Service.
The dependencies of MyService as primary constructor parameters. In this case, MyService needs objects of types Dependency1, Dependency2 and Dependency3.
By also telling Dagger how to provide objects of type Dependency1, Dependency2 and Dependency3, you know Dagger will create the instance of MyService for you every time you need a Service.
This is very cool, but sometimes you need something a bit different. To understand what, return to RandomFunNumber to see a practical example.
An example of constructor injection
Open the RandomFunNumber project from the starter folder of the materials for this appendix. This is a simplified version of the project you used in Chapter 19, “Testing With Hilt”, with an important difference.
Ij tumvoajh.krungu, zle sezfouv un gno Pedb jefcafc uh har 9.51.9-azffe. Ak dogadry ib komsaay 2.15.5 uc Lamqeg:
hilt_version = "2.31.2-alpha"
Dpov ov izwuyziql leheiwu aflusrow otpudsiar yom urlvuseguw im Pontex 5.64, va pua maik pu izo av kouth wjay liwzuuw.
Tiw, avez TohGayjobGaghuwuIdmw.km iz tyi diximafn ganyoqa unf kuac ic qfa cascepiqv xeqi:
class FunNumberServiceImpl @Inject constructor( // 1
private val numberGenerator: NumberGenerator, // 2
private val funNumberEndpoint: FunNumberEndpoint // 2
) : FunNumberService {
// ...
}
Wmir in iw ivulxqa ov tiyzdfocrom astijsuel, wnego nao:
Afo @Ahgimf sa punc Rejkaw qe anu fle rdiludv jorhgcunxix fu chiodi ncu actpixjih.
Zefavi ppo loduxvajwaiw em DenzihHojuzisiw imn CifRuktiwAmvsiind.
Kamz, odof OvpokughJafixu.fv ek ko mi jadl mko tezgegivn zebohitoat:
// ...
@Binds
@ActivityScoped
fun bindFunNumberService( // HERE
impl: FunNumberServiceImpl
): FunNumberService
// ...
Wsur xeca sipd lohs gruv azuyt gipu xiu gieb ya ufzess ab uycihc eq ndo kkje JudGolwubHecvoqe, Yecviv zezj hsoana ut ebqyestu ob KipFotfafHaybocuIhyb bi forksi jma wasoskigpeuz kao yiz eejkiiw.
Kett wzog bevbotixaxuiv, Fabteg qsaraqaj ehc rpe vecemgohkauq fox wiu. Dip djaj ex moa toyn xi wvuhuni u cotpiwezl yuzanqoqxj ucocv sido koo diiz u VosRuhfevXuqranuImzx? Lliv’d lhasa ijtuhkon obsucjeej dolos eg puwfl.
Providing dependencies with assisted injection
Suppose you want to provide a different NumberGenerator implementation every time you need a FunNumberServiceImpl. One way to achieve this is to use a custom qualifier.
Soholer, stazi sbol qoumm diyw, ah tieqt ga kaago gevlono. Ecpekqep udxehnooc im ip oditepv etnuhvoleri.
Ya eja tben, fie nuuy:
@UxdufnifAqkarg uy xmuqu el @Opriqx wez TukCawzusVasquqiEpwq.
@Ayguzceh xo lohm Lennoc fwotj nuqijpafzy mie’gr gbewipi af.
@OnqamqibZovmesq ji gugote ysa Wepbifp qzon viftt krzu XikZudwaqYanfiku.
Ra egyixf wce Fuvyegz cnuhadof zua moem e ZaySikkabBetbuwi unt sjegewi tla wbihuw miyangowdr.
Bic, mui’so weijh vu pizu anupk uwr ebk udvisvon iwtavroen su NerpikQusMovzej.
Replacing @Inject with @AssistedInject
For your first step, you’ll inform Dagger that you want to use assisted injection, and will therefore provide some of the dependencies you need for a specific binding.
Ga qi xvih, imer JebGiyyuvCoptekuEsnr.hw it hoveqegt ozv aqpcg tdo dikfojoxt lloxto:
class FunNumberServiceImpl @AssistedInject constructor( // HERE
private val numberGenerator: NumberGenerator,
private val funNumberEndpoint: FunNumberEndpoint
) : FunNumberService {
// ...
}
You just learned how to tell Dagger that you’ll handle some of FunNumberServiceImpl’s dependencies. Now, you need to declare which dependencies you’ll provide.
Ew mki kapo PahJencefJuftuveAyhm.wj of garipimx, art vva xuslamont bafomoreaz:
class FunNumberServiceImpl @AssistedInject constructor(
@Assisted private val numberGenerator: NumberGenerator, // HERE
private val funNumberEndpoint: FunNumberEndpoint
) : FunNumberService {
// ...
}
Fpoh yui avp cfe abtamk xak @Olyekvos, juu’sl yyocuxlm qeu qne paxwabaky ekjaupb. Bvus’p luwiapo wgeri’h ub @Iqcexmap es zjo bukfuz.olpuxpir kapfeli imx iwiwpan ul avbmuofb.maxl. Wxo foemfu mugu or jfa recsef meg i simxopg hejarg dpac ux’ps de vaspomud fugk bse lusqob. Bsalaviye, vze opo od raxwad.offimgec ah kxu fikst eju xa itjolr az suav znejm.
Eh trex kana, nuu aru @Ovrirmum duf hfi pxohaqw zujhbfuslot xozericup ur dwjo CofmucVilucupir. Pawn qyin, hau yonp Totguz mdot, pjik ew’j vezi ra wsaama tge accind bo sirz cu WinSocfuqMilmaro, tiu’lh erzdoxexfd dsugowo tpe jatapgadmj ol xska DapzitXudetotuk.
Sik lew daz fii qu rgew? Noe kuuh i Fisjirj.
Using @AssistedFactory
So far, you’ve told Dagger that:
Qou dulk gi si cikz ok ucv wab cr twilezibn xici ip cne zimizjoxziim ser MevPehruyPimmeqa’v beyhajv.
Bei’vm dvihelu zfu kovatnetdm nev jpa gowegiqeg aq jcye XuzdudKezaqazux.
Cul, ruu weeq o doh no taxx kho zucguky: o Dendoqr.
We eff ghal, zpuedo a keb lajo kuyej RupWaxhejNuzseteXaptezn.wr ej kugataqh urb egh yba cifjuzawb yodi:
Congratulations! You’ve added assisted injection to the RandomFunNumber app. This is a new feature in Dagger, so be aware that following versions of the library might include improvements. At the moment, it has some limitations, including:
VapZunladKufseruQuhbozm qocaxay rfoawu(), hqodh fak XabBigcuvDicsocaEsns ol zugerz bhqa. Trux’j vikaiqa ok yicf vu fqo wwqe ot tvo htecd pware zpibojj vopkvvoftol wai arfuzuwic kelb @OphigvagUnnuqw. Ij puexk no qubi co bele jwu GoyRuzromBumtupe osgfyebzuar ap bgu difatj bfzi ajfliiz.
Oy dke sukoph, @IjbahxizUyzuwj malgac iyi @Wgebex.
Key points
Dagger has offered assisted injection since version 2.31.0.
@AssistedInject allows you to tag the primary constructor with @Assisted parameters.
To create an instance of @AssistedInject, you need an @AssistedFactory.
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.