【问题标题】:How to inject with IoC into Kotlin top level functions? Do I even use IoC containers?如何将 IoC 注入 Kotlin 顶级函数?我什至使用 IoC 容器吗?
【发布时间】:2017-04-24 07:41:49
【问题描述】:

我无法关注 FP。当人们说“更惯用的风格”时,我必须明白:99% 的 Java 库不适用于 Kotlin 和 Scala 的 FP 惯用风格,对吧?好吧,我需要 Spring Boot 来快速启动 Vaadin。所以我需要注入一些豆子。

package com.x.ui

import com.vaadin.icons.VaadinIcons
import com.vaadin.navigator.Navigator
import com.vaadin.ui.MenuBar

fun createMenuBar(navigator: Navigator): MenuBar {
    val menuBar = MenuBar()
    menuBar.setHeight(null)
    menuBar.setWidth(null)

    menuBar.addItem("Dashboard", VaadinIcons.COG,
            { navigator.navigateTo("Dashboard") } as MenuBar.Command)

    return menuBar
}

那么在这种情况下我如何将SpringNavigator 注入到这个函数中呢?

由于到目前为止我有几个顶级函数,我没有 @Component 也没有 @Bean ,在 Kotlin 中使用 Spring IoC 的惯用方式是什么?我仅限于使用类还是我们有技巧可以做到这一点?

【问题讨论】:

  • 顶级函数等价于 Java 静态方法。我不确定这是否有意义,或者将依赖项注入它们是否是一种好习惯。作为一种良好的做法,恕我直言,我建议您将这些函数放在使用依赖注入配置的类中。

标签: spring dependency-injection functional-programming inversion-of-control kotlin


【解决方案1】:

问题是您有一个签名为(Navigator) -> MenuBar 的函数,但您可能想要的是一个签名为() -> MenuBar 的函数。

通常,在 OO 中,您可以通过将 Navigator 注入到构造函数中来完成此操作,保存引用,然后在调用函数时使用它。

在函数式编程中,类似的概念称为“部分函数应用程序”。这是当您将参数预先应用到函数并创建一个采用剩余参数的新函数时。在我们的例子中,我们希望预先应用Navigator,这将给我们留下() -> MenuBar的签名。

This 看起来是一篇关于 Kotlin 概念的好文章。

我建议尝试这样的事情:

// note - returns `() -> MenuBar` now, rather than `MenuBar`
fun createMenuBar(navigator: Navigator): () -> MenuBar {
    // returning a function that takes no parameters
    return { ->
        val menuBar = MenuBar()
        menuBar.setHeight(null)
        menuBar.setWidth(null)

        menuBar.addItem("Dashboard", VaadinIcons.COG,
            { navigator.navigateTo("Dashboard") } as MenuBar.Command)

        return menuBar
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-26
    相关资源
    最近更新 更多