我是Hilt/Dagger的新手,我还没有找到一个注入同伴对象的好例子。下面是我的单例和数据类。我尝试在create()函数中使用TargetNumber管理器。我正在寻找语法帮助和解释为什么。
@InstallIn(SingletonComponent::class)
@Module
data class TargetNumberManager(
val maxNumber: Int = 3, val prefix: String = "ZZ") : ITargetNumberManager {
private var currentNumber = 0
@Singleton
@Provides
override fun getNextTargetNumber(): String {
val targetNumberBuilder: StringBuilder = java.lang.StringBuilder()
targetNumberBuilder.append(prefix)
val lengthOfNumber = currentNumber.toString().length
for (i in lengthOfNumber..maxNumber step 1) {
targetNumberBuilder.append(0)
}
targetNumberBuilder.append(currentNumber++)
return targetNumberBuilder.toString()
}
}
//数据类
data class Target(
@PrimaryKey
val targetNumber: String,
val targetType: TargetType?,
val numOfElement: Int?,
val location: Coordinate?
) : java.io.Serializable {
@AndroidEntryPoint
companion object {
fun create(): Target {
@Inject var targetNumberManager : TargetNumberManager
val nextNumber = targetNumberManager.getNextTargetNumber()
return Target(nextNumber, null, null, null)
}
}
}
1条答案
按热度按时间pinkon5k1#
看起来你想要的是让Dagger创建一个对象的示例。让我来解释一下如何使用
EntryPoint
s实现这一点。我对你的匕首模块的备注
在您的类
TargetNumberManager
中:provides
函数(如getNextTargetNumber
)中使用变量,因为您提供的依赖项标记为@Singleton
:这意味着Dagger只会调用你的getNextTargetNumber()
函数1次。最好将业务逻辑(例如计入管理器、用例等)和依赖注入代码(例如将函数提供给Dagger模块)分开。你可以像这样分离计数逻辑和Dagger模块:
请注意:
@InstallIn(SingletonComponent::class)
和@Module
注解。这意味着这个类不再是一个模块。因为TargetNumberManager
看起来像一个业务逻辑的实现,它与依赖注入无关。@Inject
注解添加到constructor
。这意味着Dagger可以并且将会创建这个模块。为了让Dagger创建一个TargetNumberManager
的示例,它需要找到TargetNumberManager
的依赖关系,即maxNumber
和prefix
变量。你也需要提供它们。现在我们可以将它们提取为常量:
在
TargetNumberManager
中有了这些变化,当你想在某个地方注入它时,Dagger可以创建它。它被标记为Singleton,所以Dagger将在您注入它时提供相同的示例。Dagger需要知道当你尝试注入
ITargetNumberManager
的示例时,你想要使用哪个实现。因为你有一个接口和一个实现,但可能有其他实现的同一个接口,所以我们需要告诉Dagger使用哪一个。我们通过使用@Binds
注解来做到这一点。@Binds
方法必须是抽象的或在接口中。这里我使用了抽象类作为Dagger模块:现在Dagger知道当你询问
ITargetNumberManager
时注入哪个实现。请注意,我没有在这里放置@Singleton
,因为实现类TargetNumberManager
已经标记为@Singleton
。因此,每当你注入类型TargetNumberManager
ANDITargetNumberManager
时,它将是Singleton。如何通过入口点数获取匕首示例
EntryPoint
接口。Hilt发现了这些接口,并使组件接口扩展了这些EntryPoint
接口。使用EntryPoint
基本上就像在组件接口中添加函数一样。参见:https://dagger.dev/hilt/entry-pointsEntryPoint
可以包含一个返回对象示例的函数。通过添加一个返回类型为您的依赖项的函数,您只需要求Dagger为您创建一个示例。典型的EntryPoint如下所示:
当您需要
ITargetNumberManager
时:获取MyEntryPoint
的示例,然后获取ITargetNumberManager
的示例:如果你想在你的
Target
类中这样做:Hilt需要知道Application Context,因为它将SingletonComponent保存在Application类中。所以它会去那里获取组件。获取组件后,它将强制转换为EntryPoint接口。然后,您可以调用添加到EntryPoint中的函数。
其他注意事项:
AndroidEntryPoint
仅适用于Android入口点,例如:Activity、Fragment、View、Service、BroadcastReceiver。不适用于伴随对象或其他类型的类。参见:https://dagger.dev/hilt/android-entry-point.html@Inject
不能用于函数内部的变量。您可以将@Inject
添加到构造函数中。希望这能帮上忙。我试着解释每一点。如果您还有其他问题,请告诉我!