Koin 1.0.0 Unleashed ✨

Arnaud Giuliani
Sep 14, 2018 · 6 min read
Image for post
Image for post

Well, well, well… this is it! Dear Koin users, this is the moment to unleash our first stable version of Koin. A bit more than one year after the first version, here we are with some cool features that make your daily development easier with Kotlin & dependency injection! Let’s go 👉

Setup for Koin 1.0.0

The 1.0.0 version of Koin is available in Jcenter. As usual, upgrade your Gradle script with the new version number. Here below is the complete Koin projects that are available:

// Koin core features
compile "org.koin:koin-core:1.0.0"
compile "org.koin:koin-core-ext:1.0.0"
compile "org.koin:koin-java:1.0.0"
testCompile "org.koin:koin-test:1.0.0"
// Koin for Android
compile "org.koin:koin-android:1.0.0"
compile "org.koin:koin-android-scope:1.0.0"
compile "org.koin:koin-android-viewmodel:1.0.0"
// AndroidX
compile "org.koin:koin-androidx-scope:1.0.0"
compile "org.koin:koin-androidx-viewmodel:1.0.0"
// Koin for Spark Kotlin
compile "org.koin:koin-spark:1.0.0"
// Koin for Ktor Kotlin
compile "org.koin:koin-ktor:1.0.0"

Refer to the setup page for anything about Gradle setup.

Note that we have now the koin-core-ext project, which gather extended & experimental features (ex koin-reflect).

The Koin DSL 👍

Koin is a DSL first dependency injection framework. To declare your components you need to know only 4 keywords:

  • module— declare a module, i.e. a space to gather all your components definitions
  • single— declare a singleton definition of given type. Koin keeps only one instance of this definition
  • factory — declare a factory definition of given type. Koin gives a new instance each time
  • get— resolve a dependency in a definition

single & factory keywords help you express how to build your component with a lambda expression. In this expression, you can use the get() function, to retrieve a needed dependency from Koin container.

We make Koin “modules” and we declare some “single” or “factory” instance definitions, that’s it. Below a quick example of Koin module with Koin 1.0:

Please refer to the Koin DSL Quick Reference or the Koin DSL Documentation for more details.

Modules — definition namespace & visibility 😎

Module allows you to write your definitions. It also allows to make logical separation between definitions (namespace) and constraint their visibility.

In the snippet below, ComponentB and ComponentC will only see ComponentA definition from their module. But if we want to request a ComponentA instance, we have to use its name (else Koin won’t be able to choose between the 2 definitions).

By default, Koin will give a name to each component depending on module’s namespace. At start we will have 2 instances of type ComponentA: ComponentB.ComponentA and ComponentC.ComponentA.

Below in the snippets, is how we can retrieve those instances:

For definitions and modules, we have now 2 flags to specify additional behavior:

  • createdAtStart: create instance of module/definition with startKoin()function
  • override: definition and module override must be explicit. You have to specify override=true on definition or module that need overriding existing content.

The modules chapter from reference documentation gives more details about it.

A new Scope API ⭐️

In the previous version of Koin the release()function helped to release instances from path. This was too much implicit, and note very usable indeed.

Koin 1.0 brings the Scope API. How does it work? A scope is a fixed duration of time in which an object exists. When the scope context ends, any objects bound under that scope cannot be injected again (they are dropped from the container).

Then we need a special definition declaration, that is between single and factory definitions lifetime. Just use the scope keyword to declare a scoped definition:

module {
scope("session") { Presenter() }

A scope is tagged via a scope id, an identifier of the scope itself. To resolve a scoped definition, you need to create the associated scope with this id. Once created, the resolution will be done against the scopeId mentioned in the DSL.

This Scope API will be useful to write limited lifetime components (authentication sessions, wallet, cart…).

Check the Scope API documentation for more details.

Injection Parameters ✨

The dependency injection API allows you to use Kotlin destructured declaration directly to describe your parameter values, to inject them on the fly:

When requesting an instance, just use the parametersOf() function to specify which params to provide.

The documentation for injection parameters is available here.

Better definition declarations ☢️

Koin DSL can be seen as a bit “manual”, because you have to wire things manually in constructors with the get function.

If you are not Ok with that, here is a good news. We launched an experimental API builder to let write definitions in a smarter way, and avoid you to write constructors. You can just use the single, factory or scope definition directly with a given type, without any expression.

If you have an implementation class, to match with an interface, just use the singleBy keyword, that allows 2 types parameters: singleBy<Target,Implementation>()

All of those new keywords are still experimental (and uses a bit of introspection to get the constructor of your class). We need your feedback on it ;)

You can find it in koin-core-ext project (quick reference here).

Koin for Java developers 🌈

One big news is the coming of the koin-java project. The big idea is to bring easy start & injection to Java with static helpers:

You have to describe Koin module in Kotlin, but all your classes can be in Java! KoinComponent static helper is brought by KoinJavaComponent class and startKoin is ported by KoinJavaStarter.

Check out the koin-java Quick Reference page for more info.

Image for post
Image for post

and powerful features for Android 💪

Lots of work on the Android side! Projects have been renamed thanks to their feature inside. We have now the following Android projects:

// Koin for Android
compile "org.koin:koin-android:~"
// Koin Android Scope feature
compile "org.koin:koin-android-scope:~"
// Koin Android ViewModel feature
compile "org.koin:koin-android-viewmodel:~"

koin-android-architecture and koin-androidx have been dropped.

The newcomer is the scoping feature ported by koin-android-scope which help you bind an Android component’s lifecycle to a Koin scope. On the lifecycle’s end, Koin close the associated scope. The bindScope function will bind a Koin scope to current lifecycle.

The ViewModel Koin feature is provided by koin-android-viewmodel project and has the same target: bring easy to use out of the box dependency injection for Android Architecture ViewModel components.

Declare you ViewModel class with viewModel keyword (also available as API builder format, to avoid write constructor). Just use it in your Activity or Fragment with by viewModel() or getViewModel().

One last big thing: starKoin() doesn’t need you to run from Applicationclass anymore. The function needs only a Context instance to run and be started from any Android class if needed:

startKoin(androidContext, appModules)

The androidApplication() and androidContext() DSL functions allow you to retrieve Application and Context instances.

Go get the Android quick references to read all about it!

Ready for AndroidX ✅

For those who wants to test the new Android packaging system, we have prepared the AndroidX version of projects that are impacted:

// Koin AndroidX Scope feature
compile "org.koin:koin-androidx-scope:1.0.0"
// Koin AndroidX ViewModel feature
compile "org.koin:koin-androidx-viewmodel:1.0.0"

Features are the same than the standard package, but with new AndroidX packages.

Other changes ⚙️

For koin-ktor and koin-spark, we can now use the koin-logger-slf4jlogger to help you log with the desired logging implementation (logback, log4j …).

  • Ktor extensions have been added to Route and Routing classes.
  • Now you can use Koin inside Ktor via installKoin() and being compatible with autoreload
  • SparkJava needs you to extends SparkController interface if you want to declare a controller.

Upgrading from Koin 0.9.x? 😱

Coming from an older version of Koin? We have a dedicated page to help you: https://insert-koin.io/docs/1.0/quick-references/upgrade/

Check also the changes on the changelog file to help understand the upgrade.

Getting Started Projects on Github 🚀

All the getting started projects are available on Github or are directly downloadable with a zip file. Go check this

👉 Rendez-vous @ insert-koin.io

The new version of the website is available with great sections:

Koin developers

Latest news about Koin

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store