En la biblioteca de Injekt para Kotlin, ¿cómo inyecto funciones en lugar de solo valores?

Al usar la biblioteca Injekt en Kotlin para dependency injection:

En lugar de inyectar un valor, a veces quiero inyectar una function. Entonces algo así como recibir la function por:

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

Esto parece funcionar bien, pero no si logging más de una function con la misma firma pero diferente significado. No parece haber una manera de diferenciar las funciones.

Nota: esta pregunta fue escrita y respondida intencionalmente por el autor ( Preguntas que responden por sí mismas), de modo que las respuestas idiomáticas a los temas comúnmente solicitados de Injekt + Kotlin están presentes en SO. Otras respuestas también son bienvenidas, ¡hay otros styles de cómo hacer esto! Divulgación, soy el autor de la biblioteca Injekt.

Tiene razón, las funciones se networkingucen a una representación interna de la firma, por ejemplo en este caso como:

 kotlin.jvm.functions.Function1<? super java.lang.Integer, ? extends java.lang.Integer> 

Y cualquier function que tenga el mismo parámetro y tipo de retorno tendrá el mismo tipo interno y parecerá ser el mismo en Injekt. Los siguientes loggings son todos válidos y no entran en conflicto:

 // 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) 

Si desea utilizar la misma firma de function como significado diferente, puede crear un contenedor de class para cada significado de la function:

 class Int1Action(val function: (Int) -> Int) { operator fun invoke(i: Int): Int = function(i) } 

Al agregar el operador de invoke , puede usar naturalmente este contenedor sin hacer reference al miembro de la function , como por ejemplo:

 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 
  • ¿Podemos definir nuestros accesadores sin un valor init?
  • ¿Cómo configurar el headerView de NavigationView con Anko DSL?
  • ¿Kotlin proporciona mejoras en el performance?
  • código inalcanzable kotlin cuando se usa finalmente y enum
  • "No se puede encontrar la class referenceda" con Proguard y Kotlin
  • ¿Cómo combinar la list dentro de una list de un tipo, en una sola list inmutable?
  • ¿Cómo crear una variable que pueda tomar cadenas y funciones en Kotlin?
  • Cómo enviar / adjuntar imágenes múltiples
  • La versión 1.1.4-eap-77 de Kotlin no funciona
  • Kotlin with-statement como expresión
  • Mezcla de Kotlin con error de Java: no se puede encontrar el símbolo