在Kotlin中使用基于注释的依赖注入时,首选语法是什么?

时间:2016-05-23 10:17:31

标签: dependency-injection kotlin

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

@Inject private SomeService someService;

由于反射允许重新分配通常为final的字段,因此这也是一个有效的声明:

@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
  • Nullable类型方法需要对每个服务使用进行额外的空检查(或!!运算符),即使我们100%确定它们永远不会为空 - 除非出现完全错误,在这种情况下我们有更大的问题。
  • lateinit方法似乎在运行时执行不必要的检查(这些,很可能,不太可能成为性能瓶颈,但仍然是)并且相当冗长。
  • 这两种方法都允许将变量重新分配给另一个值。我们尚未找到用var替换val而不覆盖getter或使用备份字段的方法,该字段面临同样的问题。具有讽刺意味的是,在许多情况下,它们都比Java声明更长。

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

虽然我知道有多个框架可以使用Kotlin友好的语法来解决类似的问题(例如Injekt),但我会问,是否有更好的方法可以解决我们的问题。

1 个答案:

答案 0 :(得分:1)

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

information %>%
  complete(Zone = full_seq(Zone, period = 1), Name) %>%
  #just another way to replace NA in column X3 to X1
  mutate_each(funs(replace(., is.na(.), 0)), X3:X1)

使用此方法时,您可以使用fun <T> uninitialized(): T = null as T @Inject private val someService: SomeService = uninitialized() ,而Kotlin不会添加任何val项检查。

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