首页 > 解决方案 > 来自不同类的调用扩展功能

问题描述

我正在尝试创建一个非常简单的事务管理器,如下所示:

object PersistenceManager {
    private val dataSource: DataSource by lazy {
        val config = ConfigFactory.load()
        hikari(config.getConfig("postgres"))
    }

    private fun hikari(appConfig: Config): DataSource {
        // init datasource
    }

    fun <T> transaction(statement: Connection.() -> T): T {
        val connection = dataSource.connection
        try {
            return connection.statement()
        } catch (e: Exception) {
            connection.rollback()
            throw e
        } finally {
            connection?.close()
        }
    }
}

class BrandsDB {

    private val query = "select name from brands order by name"

    fun Connection.getAll(): List<String> {
        val ps = this.prepareStatement(query)
        val rs = ps.executeQuery()
        return JdbcMapperFactory.newInstance()
            .newMapper(String::class.java)!!.stream(rs).toList()
    }
}

class BrandsService(private val brandsDB: BrandsDB) {

    fun getBrands(): List<String> {
        return transaction {
            brandsDB.getAll() // I'd like to do something like this but since
                              // getAll() method belongs to Connecion, I can't
        }
    }
}

所以这一切背后的想法是,我可以在一个transaction块中拥有多个查询,如果出现任何问题,我可以回滚(我应该在这些查询中插入或更新)。我还想避免将连接传递给该brandsDB.getAll()方法,但让它以“隐式”方式获取连接。

我知道我可以将getAll()方法提取到它自己的文件中或使BrandsDB类成为对象,但这可以在任何地方以静态方式调用该方法,这是我不喜欢的。我也不想将任何与数据库相关的代码放在 中BrandsService,只有业务逻辑应该放在那里。

这可能吗?

标签: kotlinkotlin-extension

解决方案


Connection是 Java 中的接口(不是类!),因此您可以创建自己的接口来扩展它并委托给它。


interface OurConnection : Connection {
   fun getAll() : SomeType
}

fun <T> PersistenceManager.extendedTransaction(action: OurConnection.() -> T) : T {
   //call the original method
   return PersistenceManager.transaction {
      object : OurConnection, Connection by this {
         override fun getAll() = TODO("implement me")
      }.action()
   }
}

我使用委托实现,Connection在我的接口中隐式委托方法。它是Connection by this线,函数调用this中的 lambda 接收器对象在哪里。PersistenceManager.transaction


推荐阅读