Koin

Koin is a lightweight dependency injection framework for Kotlin, designed to be simple and easy to use, especially in Android development. Unlike Dagger, which uses compile-time annotation processing, Koin operates at runtime, making it more flexible but potentially less performant in some scenarios.

Key Features of Koin

  1. Simplicity: Koin is known for its straightforward syntax and ease of use, making it accessible for beginners.

  2. No Code Generation: Koin does not require code generation or annotation processing, which simplifies the build process.

  3. Kotlin DSL: Koin leverages Kotlin's DSL (Domain-Specific Language) capabilities for defining modules and dependencies.

Benefits of Using Koin

  • Simplicity: Koin's API is straightforward and easy to learn, making it accessible for developers new to dependency injection.

  • No Boilerplate: Koin reduces boilerplate code by using Kotlin's language features like property delegation and DSL.

  • No Annotation Processing: Since Koin operates at runtime, it does not require annotation processing, leading to potentially faster build times.

  • Flexibility: Koin's runtime nature allows for greater flexibility in managing dependencies, which can be particularly useful in dynamic or complex scenarios.

  • Kotlin-First Approach: Designed specifically for Kotlin, Koin leverages Kotlin features fully, providing a more natural and idiomatic experience for Kotlin developers.

Example of Koin in an Android Project Using Onelib

  1. Define Koin Modules:

const val BASE_URL: String = ""

val networkModule = module {

    single {
        return@single OkHttpClientFactory.create(
            interceptors = listOf(getParameterInterceptor(), getHeaderInterceptor()),
            showDebugLog = BuildConfig.DEBUG,
            certificatePinner = null,
            authenticator = null
        )
    }

    single(named(BASE_URL)) {
        BuildConfig.BASE_URL
    }

}

// if your need parameter. ex: api_key
private fun getParameterInterceptor(): Interceptor {
    val params = HashMap<String, String>()
    params["api_key"] = BuildConfig.API_KEY
    return ParameterInterceptor(params)
}

// if your need header. ex: api_key
private fun getHeaderInterceptor(): Interceptor {
    val headers = HashMap<String, String>()
    headers["Accept"] = "application/json"
    headers["Content-Type"] = "application/json"
    headers["Authorization"] = "your bearer token"

    return HeaderInterceptor(headers)
}
  1. Define Koin in Feature:

val yourFeatureModule = module {

    single {
        ApiService.createService(
            YourService::class.java,
            get(), get(named(BASE_URL))
        )
    }

    factory { ErrorParses(get()) }
    single<YourRepository> { YourDataSource(get(), get()) }
    single<YourUseCase> { YourInteractor(get()) }
    viewModel { YourViewModel(get()) }
}
  1. Start Koin in Application Class:

class App : BaseApplication() {

    override fun getDefineModule(): List<Module> =
        listOf(
            networkModule,
            yourFeatureModule,
        )

    override fun initApp() {
        Timber.plant(Timber.DebugTree())
    }
}
  1. Inject Dependencies in Activity or Fragment

class MainActivity : BaseActivity<ActivityMainBinding>() {

    private val viewModel: yourViewModel by viewModel()

    override fun initIntent() {}
    override fun initUI() {}
    override fun initAction() {}
    override fun initProcess() {}
    override fun initObservers() {}
}

if you are using jetpack compose and want to inject into a composable function

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourAppTheme() {
                YourComposabelFunction()
            }
        }
    }
}

@Composable
fun YourComposabelFunction(
    private val viewModel: YourViewModel = koinViewModel()
){
    // content
}

Koin is a powerful and easy-to-use dependency injection framework tailored for Kotlin and Android development. Its simplicity, lack of annotation processing, and Kotlin-first approach make it an excellent choice for developers who want a straightforward DI solution without the complexities and overhead of other DI frameworks like Dagger. By leveraging Koin, you can improve the modularity, testability, and maintainability of your Android applications.

Last updated