Dagger:如何检查 dagger.Lazy 变量是否已初始化

Dagger: How to check if dagger.Lazy variable has been initialised

我在此处使用 isInitialized() 找到了 Kotlin Lazy 对象的答案:

但似乎 dagger.Lazy 没有相同的 public 方法。

这就是我使用 Dagger 进行懒惰注入的方式:

@Inject internal lateinit var someService: dagger.Lazy<SomeService>

如何在不调用将初始化它的 someService.get() 的情况下检查 someService 是否已经初始化?除了引入一个布尔标志并自己跟踪它之外..

谢谢!

没有办法检查; Lazy only has one method, get, making it a or "Single Abstract Method (SAM)" interface much like JSR330's Provider, Guava's Supplier, and JDK8 Supplier.

这个抽象很重要,因为在Dagger中Lazy的定义比较复杂,实现也不止一种。对于作用域绑定,the internal InstanceFactory itself implements Lazy, so the built in Provider<Lazy<T>> available for each T in the graph can be implemented using a class ProviderOfLazy that can simply return the internal Provider or InstanceFactory rather than creating a new wrapper instance. With that in mind, the instance of Lazy you interact with might be a shared one, so a hypothetical isInitialized might be ambiguous: Does it mark that the scoped binding was ever accessed, or just the local Lazy injection point you requested? Would that behavior change based on whether you mark the binding scoped or not in a faraway Module file? You could also imagine an implementation where every Lazy injection got its own instance, and each would locally track whether it had ever had its get called regardless of scoping. This is in contrast to Kotlin's Lazy,其中每个实例只包含一个初始化函数,因此歧义较少。

此外,Kotlin 的 Lazy 在任何这些模式下都有多个 synchronization modes from which you can select, some of which have undefined behavior when called concurrently. isInitialized is never synchronized,因此在并发环境中,您可能会收到 false 而值在 mid-construction 中,甚至可能完全在不同的线程上构建,并且该值在调用 isInitialized.

的线程中还不可见

如果您需要能够检查 Lazy-like 状态,则需要指定您关心构造的范围以及 thread-safe 您希望结果如何,即自定义足以保证您自己的实施。