在 Kotlin 中使用 Injekt 库进行依赖注入(inject)时:
有时我想注入(inject)一个函数,而不是注入(inject)一个值。所以像通过以下方式接收函数:
val function: (Int) -> Int = Injekt.get()
这似乎工作正常,但如果我注册多个具有相同签名但含义不同的函数,则不行。似乎没有办法区分这些功能。
注意: 这个问题是作者有意编写和回答的 ( Self-Answered Questions ),因此常见 Injekt + Kotlin 主题的惯用答案都出现在 SO 中。也欢迎其他答案,还有其他风格的如何做到这一点!声明一下,我是 Injekt 库的作者。
最佳答案
你是对的,这些函数归结为签名的内部表示,例如在本例中为:
kotlin.jvm.functions.Function1<? super java.lang.Integer, ? extends java.lang.Integer>
任何具有相同参数和返回类型的函数都将具有相同的内部类型,并且对于 Injekt 来说似乎是相同的。以下注册均有效且不冲突:
// register some functions
Injekt.addSingletonFactory {
val function: (value: Int) -> Int = { value -> value + 1 }
function
}
Injekt.addSingletonFactory {
val function: (Long) -> Long = { value -> value - 1 }
function
}
Injekt.addSingletonFactory {
val function: (Long) -> String = { value -> "The long is $value" }
function
}
// inject and use the functions
val intFunction: (Int) -> Int = Injekt.get()
val intResult = intFunction(2)
val longFunction: (Long) -> Long = Injekt.get()
val longResult = longFunction(2)
val longStringFunction: (Long) -> String = Injekt.get()
val stringResult = longStringFunction(10)
如果您想使用相同的函数签名作为不同的含义,您可以为函数的每个含义创建一个类包装器:
class Int1Action(val function: (Int) -> Int) {
operator fun invoke(i: Int): Int = function(i)
}
通过添加invoke
运算符,你可以自然地使用这个包装器,而无需引用function
成员,例如:
Injekt.addSingletonFactory {
val function: (Int) -> Int = { value -> value + 20 }
Int1Action(function)
}
val action: Int1Action = Injekt.get()
val result = action(2) // call it directly using the invoke operator
关于dependency-injection - 在 Kotlin 的 Injekt 库中,如何注入(inject)函数而不仅仅是值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37550923/