Dagger Lazy during constructor injection

Multi tool use
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!





Have you tried?
– AutonomousApps
Jul 2 at 7:30





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.

Ez5fNFnAuaJl JGQPj0sTdQ,JbO8D1D3V wxKNJDsuajoDYEcjM4SR 1r4lbIEUhG5N6
Z,Dx7loJ

Popular posts from this blog

Rothschild family

Cinema of Italy