Dagger Lazy during constructor injection

Multi tool use
Dagger Lazy during constructor injection
I realize that the recommended way of accomplishing Lazy
injection with Dagger is to add Lazy
to a field injection point. For instance,
Lazy
Lazy
class Foo {
@Inject lateinit var bar: Lazy<Bar>
fun useBar() = bar.get().doSomething()
}
What about using constructor injection? I have not seen anyone doing it.
class Foo @Inject constructor(private val fizz: Fizz,
private val bar: Lazy<Bar>) {
fun useBar() = bar.get().doSomething()
}
To summarize when doing Dagger lazy injection, can I use Lazy<Bar>
in a constructor? Or is my only option to move Lazy<Bar>
to a field injection while keeping other non-Lazy dependencies in the same class injected via the constructor?
Lazy<Bar>
Lazy<Bar>
Thanks for any pointers!
If you immediately call
lazy.get()
in the constructor, why not just inject the plain object?– David Medenjak
Jul 2 at 7:46
lazy.get()
Good point but I actually don't call it in the constructor but only conditionally. The examples above may not be that clear.
– liminal
Jul 2 at 11:53
1 Answer
1
Constructor injection is no different from regular field injection, Lazy
-wrapped constructor arguments are acceptable.
Lazy
The only thing you need to make sure is to expose the dependency via module somewhere in the dependency graph.
I am able to do it but since I have not seen any examples of doing via constructor injection was not sure if the object graph is actually changing as expected (the Lazy object only gets added to the object graph after get() is called)
– liminal
Jul 2 at 11:55
@liminal: If your object (Bar) is not scoped (e.g.
@Singleton
), then getting it won't change the object graph; across all consumers, direct injection of Bar will create an instance, Provider<Bar>
will return a new instance each time you call get
, and Lazy<Bar>
will generate a new instance on get
and always return the same one. If your object is scoped, then calling get
will cause the object to be created for everyone, but no differently than if you had injected it aside from the delay. (For a scoped object, Provider and Lazy are equivalent.)– Jeff Bowman
Jul 3 at 17:37
@Singleton
Provider<Bar>
get
Lazy<Bar>
get
get
@JeffBowman correct, having exposed scoped dependency, the
Lazy
-wrapped instance of DoubleCheck provider
accessing the dependency is generated so we have a sort of double dependency caching done by both the Lazy
wrapper and the provider(once when the dependency is accessed for the first time). Things differ if we expose the dependency without scope - we just cache the dependency with the Lazy
wrapper only.– dawid gdanski
Jul 3 at 18:24
Lazy
DoubleCheck provider
Lazy
Lazy
@dawidgdanski Right, but I'll do you one better: There's no double dependency caching, because the DoubleCheck object that caches the value implements both Provider and Lazy, and specifically avoids caching a value that has already been cached. In that sense, a lazy injection of a scoped value doesn't involve creating a separate instance to track the lazy result.
– Jeff Bowman
Jul 3 at 19:00
Thanks. So I am doing it correctly then. The object that's injected in the constructor and wrapped in Lazy is Singleton scoped
– liminal
Jul 3 at 19:54
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Have you tried?
– AutonomousApps
Jul 2 at 7:30