在Kotlin中使用基于注释的依赖注入时,哪种语法是优选的?

我们正在使用现有的框架,其中包括通过注释提供依赖注入。 在Java中,要注入字段值,我们可以这样做:

@Inject private SomeService someService; 

由于反射允许重新分配通常是最终的字段,所以这也是一个有效的声明:

 @Inject private final SomeService someService = null; 

为了使声明更短(也使单元测试类中的字段可用,同时使它们成为半私有API的一部分),可以这样做:

 @Inject SomeService someService; @Inject final SomeService someService; 

当谈到Kotlin时,我们一直在坚持:

 @Inject private var someService: SomeService? = null @Inject private lateinit var someService: SomeService 
  • 可空类型的方法在每个服务使用上都需要额外的空检查(或者!!运算符),即使我们100%确定它们永远不会为空 – 除非出现完全错误,在这种情况下,我们会遇到更大的问题。
  • lateinit方法似乎在运行时执行不必要的检查(这很可能不会成为性能瓶颈,但仍然是),而且相当冗长。
  • 两种方法都允许将变量重新分配给另一个值。 我们还没有找到一种方法,用val替换var ,而不必重写getter或使用备份字段,它将面临同样的问题。 具有讽刺意味的是,在许多情况下,它们都比Java声明长。

那么 – 声明注释的Kotlin字段的首选方法是什么,它将被自动注入,我们100%确定它们永远不会为空?

虽然我知道有多个Kotlin友好的语法解决类似的问题(如Injekt )的框架,我问是否有更好的方法来处理我们所拥有的问题。

我在项目中使用了第三种方法。 但这是一个黑客。

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

使用这种方法时,可以使用val ,Kotlin不会添加任何null检查。

我个人希望Kotlin有一个合法的方式来实现同样的行为,但目前还没有。 前一段时间我创建了KT-10583问题,并介绍了如何解决问题。 但是我不确定这个问题在不远的将来会得到解决。