问题描述
我有一个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,A>
来代替Map<K,Provider<A>>
。 Lazy可能也可以使用相同的方法,但是Provider会尊重任何东西,而Lazy会始终对其进行缓存。
所以您可以像这样返回地图:
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>>
}