Categories
android blog koin kotlin

Koin and three ways to define a component (single, factory and scoped)

To continue where we left off in the last article, we will talk about Koin and different ways dependencies can be declared.

Singles

I use single the most when I declare my dependencies. It just means that there will be only one instance created for the entire app. Each injection will use the same instance. This is useful for repositories and long-living objects in the app. In a module, we can define a singleton this way

val myModule = module {
    // declare Service as single instance
    single { Service() }
    single { Controller(get()) }
}

Factory

In contrast to single, factory will create a new instance each time the component is injected, and this is useful when we inject presenters in the MVP architecture, or when we inject something that should be unique to the caller. To give an example:

class Controller()
val myModule = module {
    // declare factory instance for Controller class
    factory { Controller() }
}

Scoped

This is where Koin can shine. Imagine we need to keep our instances living a bit longer, so we can’t use factory but we also don’t want a singleton, so we can’t use single to create our dependencies. This is where scopes come in, we will tell Koin when we want to create a scope and from that moment on, all dependencies will live as long as the scope lives. This is useful when we want to have an auth scope and a non-auth scope to recreate our instances when a user logs in and logs out. This can help us reset our dependencies and provide new ones when the user state is changed. Think of a Retrofit instance, and how we have to inject the user token when the user is logged in so we need a new retrofit instance for that.

If anyone tried to set up scopes in Dagger they know how complicated and painful that can be. With Koin, it’s nothing like that, let’s look at an example

module {
    scope("scopeId"){
        scoped { Presenter() }
        // ...
    }
}

Here we just create a scope by name of scopeId and we can use that id to create and destroy that scope and all of its dependencies. We create our scope with this function

val scope = koin.createScope("myScope")

After we are done with this scope we can call

scope.close()

What? That easy? Of course, its Koin, we can do magic in just a few lines of code :).

Stay tuned for the next article in this series!

Leave a Reply

Your email address will not be published. Required fields are marked *