KOIN is a dependency injection framework that uses Kotlin and its functional power to get things done! No proxy/CGLib, No code generation, No introspection. Just functional Kotlin and DSL magic ;)
Check that you have jcenter
repository. Add the following gradle dependency for your Android app:
compile 'org.koin:koin-android:0.2.2'
or if you need android-support classes:
compile 'org.koin:koin-android-support:0.2.2'
First of all, you need to write a module. A module gathers your components definitions and allows it to be loaded by Koin and injected in your application. Keep in mind, that injection by constructor is the default strategy targeted by Koin.
Write a class that extends AndroidModule, overrides the context()
function and uses the declareContext
function to define a context like below:
class MyModule : AndroidModule() {
override fun context() =
declareContext {
provide { ServiceA(get()) }
provide { ServiceB() }
provide { ServiceC(get(), get()) }
}
}
//for classes
class ServiceA(val serviceB: ServiceB)
class ServiceB()
class ServiceC(val serviceA: ServiceA, val serviceB: ServiceB)
To describe your module, you can use the following Koin DSL keywords:
provide { /* component definition */ }
declares a component for your Modulebind {/* compatible type */}
bind a compatible type for provided definition (use it behind provide{} expression)get()
resolve a component dependencyscope {/* scope class */}
use the given scope for current module's definitions
Below a more complete module example, with sample weather app:
class MyModule : AndroidModule() {
val TAG = MyModule::class.java.simpleName
override fun context() =
declareContext {
// Scope for MainActivity
scope { MainActivity::class }
// provided some components
provide { WeatherService(get()) }
provide { createClient() }
// build retrofit web service with android String resource url
provide { retrofitWS(get(), resources.getString(R.string.server_url)) }
}
private fun createClient(): OkHttpClient {//return OkHttpClient}
private fun retrofitWS(okHttpClient: OkHttpClient, url: String): WeatherWS { // create retrofit WeatherWS class}
}
AndroidModule also gives you the possibility to retrieve Android specific resources directly in your module context (ApplicationContext, Resources & Assets). e.g: Get an Android string in your module:
resources.getString(R.string.server_url)
To start your module, you must build it:
val myContext = Koin().init(applicationInstance).build(MyModule())
This will return a KoinContext object. Koin proposes the KoinContextAware interface, to help define and bring your Koin context all over your app. Configure it like below:
class MainApplication : Application(), KoinContextAware {
/**
* Koin context
*/
lateinit var context: KoinContext
/**
* KoinContextAware - Retrieve Koin Context
*/
override fun getKoin(): KoinContext = context
override fun onCreate() {
super.onCreate()
// insert Koin !
context = Koin().init(this).build(MyModule())
// ...
}
}
By using KoinContextAware
interface, you will be able to use the Koin Android extensions in your Android Application.
Don't forget to use the init()
function to init Android context injection, else you won't be able to load your modules & extensions.
Once your app is configured and ready to go, you have to ways of handling injection:
- Android world (Activity,Fragment...): use the by inject() lazy operator
- Kotlin component: injection is made by constructor
Below a quick sample of using by inject<>()
in an Activity:
class MainActivity : AppCompatActivity() {
// inject my WeatherService
val weatherService by inject<WeatherService>()
...
}
That's it !
You can find a complete sample app here: github sources
This sample shows the basic concepts of:
- A Module -- Module example to create okhttpClient, retrofit and web service component
- An Application -- Setup for loading module with Android application
- An Activity -- Inject
WeatherService
into MainActivity
Check the wiki for complete documentation.
Check the kotlin slack - #koin channel