首页 > 解决方案 > 创建继承koin组件的函数

问题描述

我试图简化:

// Tag class with KoinComponent
class HelloApp : KoinComponent {

    // lazy inject dependency
    val helloService: HelloServiceImpl by inject()

    fun sayHello(){
        helloService.sayHello()
    }
}

类似于

fun sayHello() = koinComponent {
    val helloService: HelloServiceImpl by inject()
    helloService.sayHello()
}

有没有可能,或者我注定要用invoke操作员上课?

标签: kotlinkoin

解决方案


嗯,这是可行的:

首先,让我们定义服务和实现:

interface HelloService {
    fun sayHello()
}

class HelloServiceImpl(private val name: String) : HelloService {
    override fun sayHello() {
        println("Hello, $name!")
    }
}

很明显,服务会向在其构造函数中配置的人说“Hello”。

现在,koinComponent功能:

fun <T> koinComponent(block: Koin.() -> T) {
    GlobalContext.get().koin.block()
}

你的功能:

fun sayHello() = koinComponent {
    val helloService: HelloServiceImpl by inject()

    helloService.sayHello()
}

以及用法:

fun main() {
    startKoin {
        modules(listOf(
            module {
                single { HelloServiceImpl("majkrzak") }
            }
        ))
    }

    sayHello()
}

输出:Hello, majkrzak!

这一切都非常简单:为了能够使用inject委托,您需要一个 Koin 上下文。实际上,工作方式KoinComponent是使用GlobalContext

interface KoinComponent {
    fun getKoin(): Koin = GlobalContext.get().koin
}

inline fun <reified T> KoinComponent.inject(
        qualifier: Qualifier? = null,
        noinline parameters: ParametersDefinition? = null
): Lazy<T> =
        getKoin().inject(qualifier, parameters)

那么,为什么不这样做呢?我们声明该koinComponent函数,以便使用接收器block调用它的参数Koin并隐式使用该全局 koin 实例。

我们可以通过使用默认值使其更可重用:

fun <T> koinComponent(koin: Koin = GlobalContext.get().koin, block: Koin.() -> T) {
    koin.block()
}

现在我有一个问题要问你:你为什么需要它?


推荐阅读