除了既有的功能之外,Ktor 自己也多加了許多新的功能。
其中一個就是依賴注入的功能
以前 Ktor 是沒有依賴注入功能的,所以我們必須要使用 Koin 這個套件來幫我們實作。從 Ktor 3.2 之後,Ktor 已經提供這個套件,我們可以直接引用
如果是全新的專案,我們可以在建立專案時勾選這個套件
如果是既有的專案,我們可以在 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 的依賴注入今天就介紹到這邊,我們明天見!