應用程式、配置與模組
使用 @KoinApplication 進行應用程式引導
使用 @KoinApplication 來定義您的應用程式入口點:
@KoinApplication(modules = [MyModule::class])
class MyApp使用強型別 API 啟動 Koin:
fun main() {
startKoin<MyApp>()
// 或使用配置
startKoin<MyApp> {
printLogger()
}
}可用的強型別 API
| API | 描述 |
|---|---|
startKoin<T>() | 全域啟動 Koin |
startKoin<T> { } | 使用配置區塊啟動 |
koinApplication<T>() | 建立隔離的 KoinApplication |
koinConfiguration<T>() | 建立配置(適用於 Compose, Ktor) |
module<T>() | 載入單一 @Module 類別 |
modules(A::class, B::class) | 載入多個 @Module 類別 |
載入個別模組
使用 module<T>() 或 modules(vararg KClass) 直接載入 @Module 類別,無需使用 @KoinApplication:
startKoin {
module<NetworkModule>()
modules(DataModule::class, CacheModule::class)
}這對於測試或混合註解模組與 DSL 配置時非常有用:
// 在測試中 — 僅載入您需要的模組
@get:Rule
val koinTestRule = KoinTestRule.create {
module<NetworkModule>()
}INFO
module<T>() 與 modules(vararg KClass) 是虛設常式函式,編譯器外掛程式會攔截並在編譯時進行轉換。它們需要套用 Koin 編譯器外掛程式。
@KoinApplication 參數
modules:要包含的模組類別陣列configurations:要載入的配置標籤陣列
@KoinApplication(
modules = [CoreModule::class],
configurations = ["production"]
)
class ProdAppINFO
當未指定任何配置時,標記為 @Configuration(預設標籤)的模組將自動載入。
模組載入順序與覆寫
Koin 在執行期採用 後者勝出 (last-wins) 原則:當兩個模組定義了相同的型別時,最後載入的模組具有優先權。編譯器外掛程式會按以下順序從 @KoinApplication 組合模組清單:
- 自動探索的
@Configuration模組(本機 + 相依項 JAR 檔) — 最先載入 - 明確的
@KoinApplication(modules = [A, B, C])— 最後載入,依宣告順序
因此,應用程式層級的覆寫一律勝過相依項預設值:
// 在相依性函式庫模組中
@Module @Configuration
class CoreModule {
@Singleton fun feature(): Feature = DefaultFeature()
}
// 在您的應用程式模組中
@Module
class AppModule {
@Singleton fun feature(): Feature = AppFeature() // 自訂覆寫
}
@KoinApplication(modules = [AppModule::class])
class MyApp
// 載入順序:CoreModule (DefaultFeature) → AppModule (AppFeature 勝出)
// 執行期 get<Feature>() 回傳 AppFeature。在明確列出的清單中,宣告順序會被保留 — 因此 @KoinApplication(modules = [A, B, C]) 會依序載入 A、B、接著 C,而 C 會在三者中勝出。每個項目的 @Module(includes = [...]) 鏈會與該項目保持群組化。
如果一個模組同時出現在明確清單中且也被 @Configuration 探索到,它只會載入一次 — 位於其 明確指定的位置 — 因此 modules = [...] 中的宣告順序始終控制著覆寫優先權。
TIP
如果您需要在多個 @Configuration 模組之間指定特定的載入順序(而非類別路徑掃描順序),請在 @KoinApplication(modules = [Core::class, Feature::class, App::class]) 中明確列出它們 — 明確清單會遵循宣告順序。
使用 @Configuration 進行配置管理
@Configuration 註解允許您將模組組織到不同的配置(環境、變體等)中。這對於按部署環境或功能集組織模組非常有用。
基本配置用法
// 將模組放入預設配置中
@Module
@Configuration
class CoreModuleINFO
預設配置名為「default」,可以透過 @Configuration 或 @Configuration("default") 使用
您需要使用 @KoinApplication 才能從配置中掃描模組:
// 模組 A
@Module
@Configuration
class ModuleA
// 模組 B
@Module
@Configuration
class ModuleB
// 應用程式模組,掃描所有 @Configuration 模組
@KoinApplication
object MyApp多重配置支援
一個模組可以與多個配置相關聯:
// 此模組在 "prod" 和 "test" 配置中皆可用
@Module
@Configuration("prod", "test")
class DatabaseModule {
@Single
fun database() = PostgreSQLDatabase()
}
// 此模組在 default、test 和 development 中皆可用
@Module
@Configuration("default", "test", "development")
class LoggingModule {
@Single
fun logger() = Logger()
}環境特定的配置
// 僅限開發環境的配置
@Module
@Configuration("development")
class DevDatabaseModule {
@Single
fun database() = InMemoryDatabase()
}
// 僅限正式環境的配置
@Module
@Configuration("production")
class ProdDatabaseModule {
@Single
fun database() = PostgreSQLDatabase()
}
// 在多個環境中可用
@Module
@Configuration("default", "production", "development")
class CoreModule {
@Single
fun logger() = Logger()
}在 @KoinApplication 中使用配置
預設情況下,@KoinApplication 會載入所有預設配置(標記有 @Configuration 的模組)。
您也可以在應用程式引導中參考這些配置:
@KoinApplication(configurations = ["default", "production"])
class ProductionApp
@KoinApplication(configurations = ["default", "development"])
class DevelopmentApp
// 僅載入預設配置(與不帶參數的 @KoinApplication 相同)
@KoinApplication
class SimpleAppINFO
- 空的
@Configuration等同於@Configuration("default") - 當未指定特定配置時,會自動載入「default」配置
- 模組可以透過在註解中列出多個配置來屬於多個配置
使用模組進行組織
請務必使用 @Module 將您的定義組織在明確的模組中:
使用 @Module 的類別模組
若要宣告模組,請使用 @Module 註解標記類別:
@Module
class MyModule在您的 @KoinApplication 中參考模組:
@KoinApplication(modules = [MyModule::class])
class MyApp
fun main() {
startKoin<MyApp>()
}使用 @ComponentScan 掃描組建
使用 @ComponentScan 自動探索帶有註解的組建:
@Module
@ComponentScan
class MyModule這將掃描當前套件及其子套件以尋找帶有註解的組建。明確指定套件:
@Module
@ComponentScan("com.myapp.features")
class FeatureModuleINFO
@ComponentScan 會針對相同的套件跨所有 Gradle 模組進行遍歷。
類別模組中的定義
若要直接在程式碼中定義定義,您可以使用定義註解來標註函式:
// 給定
// class MyComponent(val myDependency : MyDependency)
@Module
class MyModule {
@Single
fun myComponent(myDependency : MyDependency) = MyComponent(myDependency)
}注意:
@InjectedParam(用於來自startKoin的注入參數)和@Property(用於屬性注入)也可用於函式成員。請參閱定義文件以了解有關這些註解的更多詳細資訊。
包含模組
使用 includes 屬性來組合模組:
@Module
class ModuleA
@Module(includes = [ModuleA::class])
class ModuleB在您的應用程式中參考根模組:
@KoinApplication(modules = [ModuleB::class]) // 將自動包含 ModuleA
class MyApp
fun main() {
startKoin<MyApp>()
}