¿Cuál es la syntax preferida cuando se usa la dependency injection basada en annotations en Kotlin?

Estamos utilizando un marco existente que, entre otras cosas, proporciona dependency injection a través de annotations. En Java, para inyectar valor de campo, haríamos algo como esto:

@Inject private SomeService someService; 

Como la reflexión permite reasignar campos que normalmente son finales, esta también es una statement válida:

 @Inject private final SomeService someService = null; 

Para hacer que la statement sea aún más corta (y también hacer que los campos estén disponibles en las classs de testing de unidad, mientras los mantiene como parte de la API semiprivada), puede hacerlo así:

 @Inject SomeService someService; @Inject final SomeService someService; 

Cuando se trata de Kotlin, estamos atrapados con esto:

 @Inject private var someService: SomeService? = null @Inject private lateinit var someService: SomeService 
  • El enfoque de tipo anulable requiere verificación adicional nula (o operador) en cada uso del service, aunque estamos 100% seguros de que nunca serán nulos, a less que algo salga completamente mal, en cuyo caso tendremos problemas mayores.
  • lateinit enfoque lateinit parece realizar comprobaciones innecesarias en el time de ejecución (que son, bueno, muy poco probable que se conviertan en cuellos de botella de performance, pero aún así) y es bastante prolijo.
  • Ambos enfoques permiten reasignar la variable a otro valor. Todavía tenemos que encontrar una forma de replace var con val sin replace getter o usar un campo de respaldo, que enfrenta el mismo problema. Irónicamente, en muchos casos son más largos que las declaraciones de Java.

Entonces, ¿cuál es la forma preferida de declarar campos de Kotlin anotados, que se inyectarán automáticamente y estamos 100% seguros de que nunca serán nulos?

Si bien entiendo que existen frameworks múltiples con la syntax amigable de Kotlin para resolver problemas similares (como Injekt ), estoy preguntando si hay una forma más agradable de hacerlo con lo que tenemos.

Hay una tercera forma que uso en mis proyectos. Pero es un truco.

 fun <T> uninitialized(): T = null as T @Inject private val someService: SomeService = uninitialized() 

Al usar este enfoque, puede usar val y Kotlin no agrega ninguna comprobación null .

Personalmente, me gustaría que Kotlin tenga una forma legal de lograr el mismo comportamiento, pero actualmente no hay ninguno. Hace algún time creé el problema KT-10583 y describí cómo se puede resolver el problema. Pero no estoy seguro de que vaya a resolverse en un futuro cercano.

  • ¿Cómo puedo asignar un valor al parámetro KMutableProperty?
  • kotlin 1.1.4 primitivas en class genérica
  • ¿Cuál es la forma correcta de declarar el tipo de variable en Android con Kotlin?
  • Firebase-Firerestre no puede usar dos documentos
  • Cómo acceder a los miembros de un object interno en Kotlin
  • Conversión de código creador Java Parcel a Kotlin
  • ¿es posible agregar una plantilla al getter / setter de una class de datos?
  • ¿Cuáles son los límites en el despacho dynamic / doble en Kotlin?
  • Manejando una tarea después de un Fragmento de Cargas
  • Retrofit2 y kotlin
  • ¿Hay alguna manera de vincular una propiedad a appConfig en tornadofx?