iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0

除了既有的功能之外,Ktor 自己也多加了許多新的功能。

其中一個就是依賴注入的功能

以前 Ktor 是沒有依賴注入功能的,所以我們必須要使用 Koin 這個套件來幫我們實作。從 Ktor 3.2 之後,Ktor 已經提供這個套件,我們可以直接引用

如果是全新的專案,我們可以在建立專案時勾選這個套件

dependency injection

如果是既有的專案,我們可以在 build.gradle.kts 加上

implementation("io.ktor:ktor-server-di:$ktor_version")

然後重新 build 整個專案。

引用好之後,我們就可以實作依賴注入了。

假設我們有一個 GreetingService

fun interface GreetingService {
    fun sayHello(): String
}

對應的實作是 GreetingServiceImpl

class GreetingServiceImpl: GreetingService {
    override fun sayHello() = "Hello GreetingService"
}

要讓 Ktor 知道 GreetingService 對應的實作,我們要先在框架內註冊這個服務

我們先在 Application.module() 內加上 configureFrameworks()

fun Application.module() {
    configureFrameworks()
    configureRouting()
}

configureFrameworks() 內我們加上

fun Application.configureFrameworks() {
    dependencies {
        provide<GreetingService> { GreetingServiceImpl() }
    }
}

這樣之後,Ktor 就會知道每次我們要求一個 GreetingService 時,要給我們的是 GreetingServiceImpl

我們寫個簡單的路由看看效果

routing {
    get("/test") {
        val greetingService: GreetingService = dependencies.resolve()
        call.respondText(greetingService.sayHello())
    }
}

編譯後我們到 http://0.0.0.0:8080/test 就會看到

Hello GreetingService

如果我們想調整 GreetingService 未來的邏輯,不需要去改寫既有的程式碼,而是寫一個新的實作,然後更換註冊的實作即可

fun Application.configureFrameworks() {
    dependencies {
        provide<GreetingService> { GreetingServiceNewImpl() }
    }
}

除了上面使用的 dependencies.resolve() 我們還可以使用更直覺的 by,效果是一樣的

get("/test") {
    val greetingService: GreetingService by dependencies
    call.respondText(greetingService.sayHello())
}

有關 Ktor 的依賴注入今天就介紹到這邊,我們明天見!


上一篇
Day 06:改用 R2DBC 存取資料庫
系列文
每天一點 Ktor 3.0:一個月學會 Kotlin 後端開發7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言