https://kotlinlang.org logo
#dagger
Title
# dagger
d

dave08

01/26/2022, 12:51 PM
Can I do this to get an eager singleton that runs when the component is created?
Copy code
@get:[Provides Named("foo") Singleton]
		val foo: Deferred<String?> = GlobalScope.async { ... }
g

gildor

01/27/2022, 5:24 AM
Why don’t you want to make it explicit? Create a multi set like Set<Deferred> or even Set<() -> Unit> if you don’t care about lifecycle, inject it to your Application and invoke every item of set onCreate, so it will be like a callback hook
I mean like:
Copy code
@Provides @IntoSet @Named("OnAppCreate")
fun provideFoo(): () -> Unit = ...
And inject like:
Copy code
@Named("OnAppCreate") 
val onCreateActions: Set<() -> Unit>

fun onCreate() {
   onCreateActions.onEach { it() }
}
You may avoid multi set if you just have only 1 case or you want to make it even more explicit and inject all those actions separately, just remove @IntoSet annotation and Set from injection point
d

dave08

01/27/2022, 1:51 PM
Yeah, the problem is that I need to inject the
Deferred
somewhere else and
await()
it... I'm hoping that from the application's start till I actually need it, I'll already have access to the ready result...
How can I both get it into that set (with one interface for all the onCreateStartups), AND have it available seperately to access it's result?
g

gildor

01/27/2022, 2:02 PM
Yes, because deferred already caches result, you can inject in multiple places, just don't forget to add scope annotation
Though it looks that it would be easier to use if you would move this logic to own class and separate lambda which will preload it on app start, so any code which need this result would just inject a proper class (repository?) Instead of some abstract deferred
d

dave08

01/27/2022, 2:06 PM
True, but there's no real logic there... it's basically a value retreived from a shell command...
g

gildor

01/27/2022, 2:08 PM
Looks still like a logic of interaction with external service
d

dave08

01/27/2022, 2:13 PM
So just to make the interaction with the shell, it's better to even create a single method class? For now, that shell is basically a top level function, but maybe you're right. Although Android has me used to avoiding getting to the function limit before multidex... which in our case has caused problems in the past. But I guess there's a line to draw up to where we should take that! Thanks for the advice!
g

gildor

01/28/2022, 1:57 AM
avoiding getting to the function limit before multidex
But you create new class even here, this async block lambda is a new class too
So just to make the interaction with the shell, it’s better to even create a single method class?
It’s definitely doesn’t look as a work for DI for me, essentially you using an external tool inside and even cache result of it Class is easier to extend, it encapsulates logic, it can be tested and also has more friendly API for client code, you inject it by name and call a function with some meningful name instead of just Deferred<String> with qualifier
👍 1
56 Views