kotlin + aws lambda 需要空构造函数
kotlin + aws lambda requiring empty constructor
我有以下 class 用 lambda 调用的 Kotlin+Guice 编写的
class LambdaProcessor @Inject constructor(private val s3Util: S3Util) {
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
这非常适合单元测试,但 lambda 要求 class 有一个空的构造函数。
我可以通过这样做将相同的 class 转换为空构造函数:
class LambdaProcessor {
@Inject lateinit var s3Util: S3Util
init {
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
该代码现在在 lambda 上运行良好,但我不能再在我的单元测试中模拟 s3Util,因为调用了 init 方法。
我怎样才能使这两种情况一起工作?
您始终可以声明次要 constructors。然而,它们都需要调用主构造函数,所以有一个技巧可以使它 private
并相应地处理 init 块中的参数。
我不使用 Guice
但您可以尝试这样的操作:
class LambdaProcessor private constructor(s3Util: S3Util?){
@Inject
lateinit var s3Util : S3Util
init{
s3Util?.let { this.s3Util = it }
}
// passes null to primary constructor, leaving field uninitalized
constructor() : this(null){
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
// passes non-null to primary constructor initializing the field (cast to nullable needed to match primary signature)
constructor(s3Util: S3Util) : this(s3Util as S3Util?)
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
在 Kotlin 中,如果您有一个默认构造函数,那么所有其他构造函数 必须 调用您的默认构造函数。但是,您可以有多个构造函数 而没有 默认构造函数。这是我们使用的最终代码。
class LambdaProcessor {
@Inject private lateinit var s3Util: S3Util
/**
* Lambda calls the no-arg constructor, use our IoC library to initialize our dependencies
*/
constructor() {
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
/*
* Unit-testing constructor
*/
constructor(s3Util: S3Util) {
this.s3Util = s3Util
}
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
我有以下 class 用 lambda 调用的 Kotlin+Guice 编写的
class LambdaProcessor @Inject constructor(private val s3Util: S3Util) {
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
这非常适合单元测试,但 lambda 要求 class 有一个空的构造函数。
我可以通过这样做将相同的 class 转换为空构造函数:
class LambdaProcessor {
@Inject lateinit var s3Util: S3Util
init {
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
该代码现在在 lambda 上运行良好,但我不能再在我的单元测试中模拟 s3Util,因为调用了 init 方法。
我怎样才能使这两种情况一起工作?
您始终可以声明次要 constructors。然而,它们都需要调用主构造函数,所以有一个技巧可以使它 private
并相应地处理 init 块中的参数。
我不使用 Guice
但您可以尝试这样的操作:
class LambdaProcessor private constructor(s3Util: S3Util?){
@Inject
lateinit var s3Util : S3Util
init{
s3Util?.let { this.s3Util = it }
}
// passes null to primary constructor, leaving field uninitalized
constructor() : this(null){
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
// passes non-null to primary constructor initializing the field (cast to nullable needed to match primary signature)
constructor(s3Util: S3Util) : this(s3Util as S3Util?)
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
在 Kotlin 中,如果您有一个默认构造函数,那么所有其他构造函数 必须 调用您的默认构造函数。但是,您可以有多个构造函数 而没有 默认构造函数。这是我们使用的最终代码。
class LambdaProcessor {
@Inject private lateinit var s3Util: S3Util
/**
* Lambda calls the no-arg constructor, use our IoC library to initialize our dependencies
*/
constructor() {
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
/*
* Unit-testing constructor
*/
constructor(s3Util: S3Util) {
this.s3Util = s3Util
}
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}