Dependency Injection with Koin
Relevant source files
The following files were used as context for generating this wiki page:
FlowBell utilizes Koin as its primary dependency injection (DI) framework to maintain a clean architecture and ensure modularity across the application. By leveraging Koin 3.5, the project implements constructor injection for ViewModels, Use Cases, and Repositories, keeping the "wiring" of the application tidy and testable.
Sources: README.md:95-96, README.md:126-127
DI Architecture Overview
The dependency injection container is organized into three distinct modules reflecting the project's clean architecture layers: dataModule, domainModule, and presentationModule. This separation ensures that dependencies flow in a single direction and that implementation details remain hidden from higher-level components.
The diagram above shows the initialization and dependency flow between the primary Koin modules. Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/app/App.kt:47-51
Module Definitions
Data Module
The dataModule provides singleton instances for local storage, networking utilities, and repository implementations. It handles the instantiation of the Room database (FlowBellDatabase), various DAOs, and the DataStoreManager.
| Component Type | Provided Class/Interface | Description |
|---|---|---|
| Database | FlowBellDatabase | Main Room database instance using androidContext(). |
| DAO | AppPreferencesDao | Data access for app-specific settings. |
| DAO | NotificationQueueDao | Data access for the notification queue. |
| DataSource | DataStoreManager | Manages user preferences via Jetpack DataStore. |
| Repository | AppRepository | Implementation: AppRepositoryImpl. |
| Repository | UserPreferencesRepository | Implementation: UserPreferencesRoomRepository. |
| Utils | HttpRequestUtils | Utility for executing webhook requests. |
Sources: app/src/main/kotlin/com/fathiraz/flowbell/core/di/DataModule.kt:28-60
Domain Module
The domainModule provides use cases as factory instances. These classes contain the core business logic of the application and act as intermediaries between the presentation layer and the data layer.
GetNotificationStatisticsUseCase: Aggregates data for the analytics dashboard.SendWebhookUseCase: Manages the logic for forwarding notifications.ManageAppPreferencesUseCase: Handles per-app notification toggles.ManageUserSettingsUseCase: Controls global settings like theme and filters.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/core/di/DomainModule.kt:15-33
Presentation Module
The presentationModule is responsible for providing ViewModels using the viewModel DSL. This integration with koin-androidx-viewmodel allows for lifecycle-aware dependency injection into Compose screens.
The diagram illustrates how the Presentation Module resolves dependencies for specific ViewModels. Sources: app/src/main/kotlin/com/fathiraz/flowbell/core/di/PresentationModule.kt:23-53
Initialization
Koin is initialized during the application startup within the App class. The startKoin function is called inside onCreate, where the androidContext is set and the three main modules are loaded.
// app/src/main/kotlin/com/fathiraz/flowbell/presentation/app/App.kt:47-51
startKoin {
androidContext(this@App)
modules(dataModule, domainModule, presentationModule)
}
This early initialization ensures that all dependencies are ready before any UI components or background services (like the NotificationListenerService) attempt to access them.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/app/App.kt:47-51, README.md:112-113
Summary
By using Koin, FlowBell achieves a highly decoupled architecture where components like WebhookViewModel can receive a UserPreferencesRepository without knowing whether it is backed by Room or DataStore. This setup supports the project's goal of being a "developer tooling first" codebase that is easy to explore and extend.
Sources: README.md:52, app/src/main/kotlin/com/fathiraz/flowbell/core/di/DataModule.kt:44-46