Annotations for Koin

Arnaud Giuliani
Koin developers
Published in
4 min readMar 1, 2022

--

Hi Koin users 👋 I’m pleased to share with you a new Koin project. The idea is to introduce a new way to declare modules and components in Koin, and also to help introduce a new tooling capacity.

Let’s explore the new koin-annotations & koin-ksp-compiler projects. Here is the first beta version 1.0.0-beta-1.

Andrew RidleyUnsplash

The need for annotations? 🤔

The idea is not to replace the Koin DSL, as it’s the core value / the DNA of the project. But rather propose a new complementary way for components & modules declaration in Koin. In a way, annotating components can be easier for big projects, rather than declaring everything by hand in a module file.

Here is a new proposal for Koin: just tag your component class with a simple annotation, we will generate all the Koin module declarations for you!

We keep the same “semantic” as for the DSL. You will find the same keyword but as annotations: @Single, @Factory, @KoinViewModel , @Scoped …

Improving Developer Experience 👍

One capacity that opens this annotations approach, is the possibility to analyze everything at compilation and prepare more content for you (which is not possible with DSL, as it’s entirely dynamic — resolved at runtime).

The idea behind annotation processing is to generate as much content (module declarations) as we can, to avoid you writing the same kind of content as you would declare with DSL. The annotation processing is based on the Google KSP project, allowing us to work at the Kotlin compiler level to generate code.

This is very important for us to not reproduce the hard experience and pains of other code generation tools, and then it was a hard requirement: we need to have almost no impact at compile time! On our latest benchmark, the KSP processing took less than 2 seconds to process and generate code for 900 annotated components. We believe it’s a good trend in terms of sizing.

Our plugin based on KSP is also multiplatform, allowing us to bring it to Kotlin Multiplatform projects.

Let’s see how this new way to declare things works.

Quick Setup 📦

First, you need to setup the KSP Gradle Plugin for your project. Add the plugin to your root build.gradle file:

plugins {
id "com.google.devtools.ksp" version "1.6.10–1.0.2"
}

We use KSP as 1.6.10–1.0.2.

Add the Koin Annotations dependency to your Koin project. We need to use the latest Koin version 3.2.0-beta-1. Here are our dependencies:

dependencies {    implementation "io.insert-koin:koin-core:3.2.0-beta-1"
implementation "io.insert-koin:koin-annotations:1.0.0-beta-1"
ksp "io.insert-koin:koin-ksp-compiler:1.0.0-beta-1"
}

Don’t forget to make your KSP generated sources accessible:

// KSP - To use generated sources
sourceSets.main {
java.srcDirs("build/generated/ksp/main/kotlin")
}

👉 Source code is available here: build.gradle

On the Koin website, there is already some quickstart guides available: Kotlin quickstart, Android quickstart. In the following lines, we will play with the Kotlin app.

Declaring your Components ✨

As said before, we keep the same “semantic” as the original Koin DSL. For the Coffee Maker app of the Kotlin quickstart, we can just tag our classes like following:

We tag each of our component classes to be declared in Koin, with @Single annotation. This will declare our component as aSingletoninstance in Koin (like single { } DSL definition ). Types and dependencies … mostly everything is detected for us.

👉 Components sources are available here: component classes.

More about definitions declaration can be found on online documentation: Koin Annotations — Definitions

Gathering Components in Modules 🎉

To gather our definitions we need a class. We tag our class with the @Module annotation to make it a Koin module:

We also add the @ComponentScan annotation with a target package, to scan and gather all definitions of the given package.

👉 The module source code is available: CoffeeAppModule.kt

There are many ways to organize your modules. Take a look at how you can tag a Module class: Koin Annotations — Modules.

You can of course declare explicit definitions via your Module class function if you don’t want to scan for annotated components. You can even use a default module if you don’t want to handle modules at all.

Start your Annotated Module 🚀

You are now ready to use the standard startKoin { }function. Just call your module class instance: CoffeeAppModule().module. The .module extension is generated by Koin KSP to expose your Koin module. Don’t forget to use the KSP generation import:

import org.koin.ksp.generated.*

Here is the complete start:

Here we go! You can now play with your dependencies. From here you can also mix DSL modules and Annotated modules.

👉The complete project sources are available: project sources.

Just use Koin ✨

Your modules are now generated by Koin KSP Compiler. Just use the regular Koin API:

class CoffeeApplication : KoinComponent {
private val maker: CoffeeMaker by inject()
}

You can find the complete quickstart guides for Koin Annotations online:

We need your feedback 👍

Let us know what you think about this new feature. Hope this will help many people get into Koin development.

Documentation & Sources 🌐

All the documentation is available at: https://insert-koin.io/docs/reference/koin-annotations/annotations

The Github project is available here: https://github.com/InsertKoinIO/koin-annotations

Stable Release & Support 🚚

The current beta version will evolve and bring first fixes. We need your feedback on these new amazing Koin features 🤟

The stable release is planned to land in Q2. Open Source support will be shared on the Github project. Kotzilla will bring commercial support.

--

--

Arnaud Giuliani
Koin developers

Creator/Maintainer of Koin framework -- Kotlin Google Dev Expert -- Cofounder @ Kotzilla.io