Dagger 2 惰性初始化地图条目

Dagger 2 lazy initialize map entries

我有一个 Dagger 模块和组件,定义如下。我只想在从地图中获取资源时而不是在服务启动时在模块中创建资源。我尝试使用 Lazy,但不确定如何实现。

@Module
public abstract class ExpensiveObjectModule {

    @Singleton
    @Provides
    @IntoMap
    @UniqueKey(Key.A)
    static ExpensiveObject provideKeyAExpensiveObject() {
        return new ExpensiveObject(Key.A);
    }

    @Singleton
    @Provides
    @IntoMap
    @UniqueKey(Key.B)
    static ExpensiveObject provideKeyBExpensiveObject() {
        return new ExpensiveObject(Key.B);
    }
}
@Singleton
@Component (modules = {
        ExpensiveObjectModule.class
})
public interface HandlerComponent {
    Map<Key, ExpensiveObject> getExpensiveObjectByKey();

}
handlerComponent.getExpensiveObjectByKey().get(key);

只要你可以注入 A,你也可以注入 Provider<A>,所以你可以用 Map<K, Provider<A>> 而不是 Map<K, A>。这可能适用于 Lazy,但提供者会尊重某些东西的任何范围,而 Lazy 会始终缓存它。

所以你可以 return 这样的地图:

Map<Key, Provider<ExpensiveObject>> getExpensiveObjectByKey();

一个最小的例子(但在 Kotlin 中)如下所示:

@MustBeDocumented
@Target(
    AnnotationTarget.FUNCTION,
    AnnotationTarget.PROPERTY_GETTER,
    AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class Key(val value: String)

@Module
object ModFoo {

    @Provides
    @IntoMap
    @Key("foo")
    fun foo(): Any = "Foo"

    @Provides
    @IntoMap
    @Key("bar")
    fun bar(): Any = 3
}

@Component(modules = [ModFoo::class])
interface Foo {
    val foo: Map<String, Any>
    val fooProviders: Map<String, Provider<Any>>
}