Dependency Injection with Koin and Kotlin in Android

There are a lot of reasons to use Dependency Injection, or even a Framework for it.

In this Article you’ll learn what Dependency Injection is, what benefits and downsides it has and how to use it with the usage of the Koin Framework.

Let’s look at a example of a House with a Doorbell to better understand what dependency injection is.

The House class has a function that returns a String representing the current Ringtone according to the installed doorbell.

Without Dependency Injection:

class House() {
    private val myDoorbell: Doorbell
   
   init {
       myDoorbell = SpeakingDoorbell()
   }
   
   fun ringDoorbell(): String {
       return "Current ringtone " + myDoorbell.getRingtone()
   }
}

fun main() {
    val myHouse = House()
   
    println(myHouse.ringDoorbell())
}

With Dependency Injection:

class House(private val myDoorbell: Doorbell) {
   fun ringDoorbell(): String {
       return "Current ringtone " + myDoorbell.getRingtone()
   }
}

fun main() {
    val myDoorbell: Doorbell = SpeakingDoorbell()
    val myHouse = House(myDoorbell)
   
    println(myHouse.ringDoorbell())
}

As you can see in the variant without Dependency Injection the House class has a direct dependency to the SpeakingDoorbell class.

With Dependency Injection this reference no longer exists. The only reference
remaining is to the generalized Doorbell Interface.

Benefits of Dependency Injection

Flexibility

Lets suppose another class FunnyDoorbell should be used in the future, which also implements the Doorbell interface.

Exchanging the SpeakingDoorbell class later on is less work with Dependency Injection.

In the first example the House class would have to change its implementation to switch to the FunnyDoorbell class.

But with Dependency Injection this change can be done without touching the House class.

In fact the House class does not even know whether it got an instance of SpeakingDoorbell or FunnyDoorbell.

This allows to write more flexible code which can be modified and extended easier.

A looser coupling between classes is achieved.

Testability

When writing tests one cannot test the House class in the first example in isolation to the SpeakingDoorbell class.

With Dependency Injection it’s very easy to insert mocks instead of the real instance.

Downsides of Dependency Injection

There is one part that got more complex though. The main function now knows not only the House class, but also the SpeakingDoorbell class.

This ultimatley leads to a really big main function, that knows almost every component.

In this small example this is no issue, but when developing large applications we want the benefits of Dependency Injection, but as few downsides as possible.

This is exactly where Dependency Injection Frameworks comes into play!

They help to structure the whole block how and when to instantiate which classes and usually bring with them a bunch of useful features.

So let us look into the Dependency Injection Framework Koin.

Setting up Koin

Gradle

Add the following to your gradle configuration.
Get the latest Koin version [here](https://insert-koin.io/docs/setup/v3).

// Add Maven Central to your repositories if needed
repositories {
    mavenCentral()    
}
dependencies {
    // Koin for Android
    implementation "io.insert-koin:koin-android:$koin_version"
}

Application

Create an application class if you have none yet (don’t forget to add it to the manifest).

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
     
        startKoin {
            androidContext(this@MyApplication)
            modules(
                module {
                    single { House(get()) }
                    single<Doorbell> { SpeakingDoorbell() }
                }
            )
        }
    } 
}

Profit

That’s it! This is the basic Koin setup. As you can see the House class now even fetches its needed instance of Doorbell.
Simply call startKoin, configure the AndroidContext and define some Beans. These can also be injected like this into Android components like activities:

val myVariable: MyVariableType by inject()

ViewModel injection

The avid reader might already have noticed something. “What about our ViewModels. They have a lifecycle and should not get created just like that”.

To fix this issue there exists an extension for Koin.

Instead of declaring a Bean like that

single { MyClass() }

we use

viewModel<MyViewModelType> { MyViewModel() }

The injection is then done inside the fragment like that:

val myViewModel: MyViewModelType by viewModel()

Conclusion

Using Dependency Injection, especially with a framework, can be intimidating for a new programmer.

But in the most cases the positive aspects outweigh the negatives and the complexity of setting up a dependency
injection framework is quite low.

There are a lot of other things Koin can do like defining factories instead of singles, directly helping out with tests, instantiating fragments, or much more.

Have a glance at the official documentation

Useful tips to stay ahead of chaos

These little “life hacks” saved me a lot of trouble

Never leave your flat / house without your keys

Kids can lock you out when you just bring out the trash, wind can blow the door shut. Do it even when your partner pretends to have a key on his/her own 🙂

Stow away spare keys to your flat at friends or relatives

Even if you apply rule number #1, Murphy’s gonna get you: we had our keys in the car but we closed the garage door prematurely…

Prepare your stuff the evening before

Put out the clothes you wanna wear, pack your bags, prepare breakfast, fill up the gas in your car.

Never search for essential things in the morning. It drains your energy.

When you hang out your clothes the night before be spare one decision to make in the morning. #decisionfatigue

Check your flat before bedtime

My wife sometimes forgets to close the garage door. I forget to close the window to my basement room. All windows closed? Lights turned off? Doors locked? Keys back at the key board?

Always do shopping with a shopping list

Buying things you do not need and forgetting things you desperately need can ruin your weekend. And it prevents throwing away food as well!  Individual sustainable lifestyle tips

Leave a shopping bag in your car

Even if you have a shopping routine and everything on your list, well, Murphy.

Having to put stuff piece by piece into your trunk is grueling and at home you do it in reverse. So don’t.

Use Debit Card for purchases / avoid cash

Cash diffuses into nothingness without leaving a trace. If you want to have control over your finances make your money traceable.

Put an emergency hammer into your car

Plan a follow up at your hairdresser

Hairdressers always have a full schedule and at the time you realize your hair needs a cut it’s hard to get an appointment. Same goes for dentists.

Buy a leatherman or victorinox tool

Use a hanging filing systems

 

Use a housekeeping book

A housekeeping book or a budget planner makes it easier for you to reach your financial goals.

Clean Personal Finance

Thoughts on Personal Finance

Make backups of your phone and computer

No backups – no mercy

Use a Bullet Journal

Nothing changed my life so drastically in the last couple of years like the Bullet Journal Method.

Fumbling with to-do lists, habit tracking apps, a Kanban board in the kitchen, a google docs spreadsheet for goals and a mood journal I grew tired of not having one single source of truth regarding my life planning.

Read what the Bullet Journal

can do for you.

 

 

 

 

 

 

 

 

 

 

 

 

My book writing workflow

In this article I want to give you a short overview of my book writing process which I use in my current project “Level Up!”

Content Overview

For planning purposes I use Google Docs. Everything is tracked in a spreadsheet. I use task based planning.

I’m aware that making a backing track usually needs more effort than exporting the tracks or generating QR codes, but this high level overview works for me.

Percentage of Completion

A pie chart shows the ratio between open and finished tasks.

To calculate the number of tasks in a row, we count the checkboxes per column which is done with the formula:

=COUNTIF(B2:B57; FALSE) + COUNTIF(B2:B57; TRUE)

The finished tasks are counted with:

=COUNTIF(B2:B57; TRUE)

Open tasks are “all tasks – finished tasks”

Then we sum up the open and finished rows to get the data for the pie chart.

Writing in markdown

markdown is a good choice if you want to focus on writing the content. It gives my texts enough structure (headlines 1 – 4) without distracting me to much.

# H1 Headline

## H2 Headline

### H3 Headline

### Lists

#### Unordered Lists
* list item 1
* list item 2
* list item 3

### Text styling

**Bold text**

_Italic text_

~~strikethrough text~~

    one line code

```python
import math
print(math.pi)
```

Tables can be inserted in HTML

Converting with pandoc

Pandoc is great to convert any kind of text to other formats like PDF, HTML or Word (.docx)

The basic conversion looks like this:

pandoc metadata_de.yaml -o ./level_up_de.pdf --from markdown -V lang=de-DE level_up_de.md

Due to the fact that I have one file for each chapter and generate multiple formats it gets a bit more complicted than this. You can read about the details in my bash tutorial

 

Developer Toolbelt – private edition

Inspired by the Blog Post https://gingter.org/2016/12/15/my-developers-toolbelt-2016 I want to share what my tool set looks like in 2022:

  • PyCharm as main IDE for Python and markdown
  • pandoc for converting markdown to PDF
  • Android Studio
  • Github (now with private repo support)
  • Guitar Pro Version 7.5 (Thomann Affiliate Link)
  • Logic Pro X
  • Spotify for getting into “the Zone” – Currently Hooray! Hooray!
  • Tomato Timer for doing Pomodoro
  • Firefox with iMacros / Greasemonkey for browser automation / optimization
  • yED for diagrams
  • Google Spreadsheet for Content Calendar & and book writing process

I really love PyCharm and it gets better with every update. It’s currently my Swiss army knife. I even use it for managing github repos which don’t involve code 🙂

Bullet Journal

Nothing changed my life so drastically in the last couple of years like the Bullet Journal Method.

Fumbling with to-do lists, habit tracking apps, a Kanban board in the kitchen, a google docs spreadsheet for goals and a mood journal I grew tired of not having one single source of truth regarding my life planning.

The Bullet Journal Method filled that hole in my heart.

The cool thing about the concept is that it is not a “one size fits all” approach or a “my way or the highway” thing.

It is flexible and adaptable. For me personally it evolved with every month I’ve used it since the beginning of 2019.

Continue reading “Bullet Journal”

How to connect to your ESP32 on macos

To find out as what USB device the ESP32 is connected, open Terminal and enter:

ls /dev/tty* | grep usb

in my case I got

/dev/tty.usbserial-14120

Now we can connect via screen:

screen /dev/tty.usbserial-14120 115200

When you reset the board you should see something like this

configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:5656
load:0x40078000,len:12696
load:0x40080400,len:4292
entry 0x400806b0

To end the session in screen, press Ctrl+a, and type :quit and press Enter.

 

New Year’s Resolutions & Technology Learning Roadmap 2022

3D-Printing

As a belated Christmas gift for myself I’ve ordered a 3D-Printer from Prusa Research. I have some ideas in mind how to use it.

Coding

This year I want to focus on my strength and concentrate on just a few things:

  • Python & Pandas
  • Kotlin & Android
  • Advent of Code

Music

I want to record, mix and publish a song called “Unbreakable”

I will finish the print version of my guitar book “Level Up!” and publish the Android App in the PlayStore

Reading

General Goals

  • Make a test drive with a Hyundai IONIC 5
  • Get 5 guest articles for this blog

Pipenv Easter Egg

I’ve found this little easter egg hidden in pipenv:

if not environments.PIPENV_HIDE_EMOJIS:
    now = time.localtime()
    # Halloween easter-egg.
    if ((now.tm_mon == 10) and (now.tm_mday == 30)) or (
        (now.tm_mon == 10) and (now.tm_mday == 31)
    ):
        INSTALL_LABEL = "🎃   "
    # Christmas easter-egg.
    elif ((now.tm_mon == 12) and (now.tm_mday == 24)) or (
        (now.tm_mon == 12) and (now.tm_mday == 25)
    ):
        INSTALL_LABEL = "🎅   "

https://github.com/pypa/pipenv/blob/main/pipenv/core.py