在Kotlin的Injekt库中,我如何注入函数而不是值?

在Kotlin中使用Injekt库进行dependency injection时:

有时我想注入一个函数,而不是注入一个值。 所以像通过以下方式接收function:

val function: (Int) -> Int = Injekt.get() 

这似乎工作正常,但不是如果我注册多个函数具有相同的签名,但意义不同。 似乎没有办法区分这些function。

注意: 这个问题是由作者故意编写和回答的( 自我回答问题 ),所以对于常见的Injekt + Kotlin主题的习惯性的回答在SO中出现。 其他答案也欢迎,还有其他样式的如何做到这一点! 披露,我是Injekt图书馆的作者。

你是对的,函数归结为签名的内部表示,例如在这种情况下:

 kotlin.jvm.functions.Function1 

而任何具有相同参数和返回types的函数将具有相同的内部types,并且看起来与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