KOtlin Dependency Injection (KODI)

Hello developers. Everybody now uses some dependency injection into your project. Some of them have annotation processing some of them use kapt-plugin or reflection, but now I want to tell you how was written my own dependency injection framework with few lines of code and implementations. I wrote some DI-containers before with different realizations and I had used a lot of “ready for production” frameworks such as Dagger, Kodein, Koin, Lightsaber, Toothpick, etc. But no one of them doesn’t satisfy my needs. And I think, what if I create my own cool Service Locator realization by Kotlin language. This is how KODI was born. The first version has used the kotlin-reflection library and it was good. So I start to think about independent module without reflection with all Kotlin language features like infix functions, inline classes, extensions, and delegations. Here will describe how I made this!

API Syntaxis

First of all, choose the right human syntax. I really love how Kodein names this, so I going to imitate its syntax.
this is how you can create your instance binder to DI-container. is an inline extension function that creates inline class that holds a key for DI-reference. is an another cool Kotlin feature called infix operator. And then it has three types of binding: — mean that only one instance of an initialized class will be binded. It’s also a lazy function; provide called function or object reference every time its executed; — for the constant values. You can bind instances into DI-graph by its class name like or by tag . To start to initialize binding into containers you need to be in the context of Kodi framework by calling and start to declare functions into including lambda expressions. There is a simple example of how to do it below.

Another one great feature is a SCOPES with key , which tells the instance namespaces. By default, all dependencies have default scope, but you can specify it explicitly as a string constant, and retrieve it later in any part of your code with .

This all that you need to do to create a simple dependency graph. Moreover, it doesn’t matter what order you assign the dependencies to, they will all be injected lazily. It’s can be done in class or , which I’ll tell you more about it later.

Injection Methods

As I said earlier, the KODI does not use any annotation processing or reflection library until version 1.4.+. Only pure Kotlin code. So this is so simple to inject your dependencies into target class. Just implement interface to get all features of KODI injection. Next code snippet will show you how to inject your instances with delegation properties in Kotlin.

  1. - You can get an instance by lazy , that get value only for property, which is a part of KODI Framework. Also, you can get for . It’s always lazy read-write properties.
  2. Directly get selected class to be injected into the property from DI-Container

This is a really simple way to get all your dependencies in any part of your code.

Kodi Modules

Every big project has separated modules in it like module or module, or features modules, etc. can help you to manage your project architecture in a CLEAN way. There had been developed a great feature called . This is a simple container for all of your bindings into the dependency graph. Every module can have SCOPE names too. So look at the example below:

As you can see the way to create a module is to call high-order function and bind all necessary dependencies in it. Also, you can use the module scope name to specify a scope. It will automatically be added for all instances inside this module without inner SCOPE declarations with keyword. Next step to add a module into your main project graph is to call function,- declarations. Import can be used in another module that’s mean that we can combine modules with each other.

AnnotationProcessing

Next big thing in KODI that no one Kotlin dependency injection frameworks have (Koin & Kodein), - is annotation processing with . There are a few annotations that exist in KODI framework that can generate modules for you: , , ,

and works only with classes(statics and singletons) and methods (abstract and high-order) to automatically generate methods into modules with holder methods like and . IgnoreInstance and WithInstance work properties and method params. the annotation will ignore some instances to inject into your module binding. Using annotation you can specify what type of instance you want to inject into field or property. You need to implement library for kapt annotation processing. Let’s look at the example:

No boilerplate code anymore. It also reduces the chance of making a mistake if your dependencies and their input parameters change or are removed in the future. We can use annotations with Kotlin singleton methods and higher-order functions.

You can use methods, methods and interface methods for binding injections into the dependency graph. Here was a simple example of how to use this framework and you can find a full documented code into my repository with an example of usage in the typical android application. It’s been over 2 years since the first version of this framework was released. Now I have three modules in the project:
- . This is the main core framework module, which contains base abstractions, implementations, and annotations.
- . This module was created only for usage in android development. It contains all services that android framework has used since version SDK 14.
- . Module for generating code via annotation processing for KodiModules.
- . Old legacy module created for use with Kotlin reflection without any bindings and have less boilerplate code style.

KODI is a constantly growing library with simple usage syntaxis. Just add an implementation to your project and try it out:

and for annotation processing use:

Thanks for reading this article. Make some claps if you like it and please support me on github. Have a good day and write a clean readable code :)

Lead Software Developer. Kotlin enthusiast, Android developer, Swift lover, Clean Architecture Supporter