Injecting in Android
Once you have declared some modules, and you have started Koin, how can you retrieve your instances in your Android Activity Fragments or Services?
Ready for Android Classes
Activity, Fragment & Service are extended with the KoinComponents extension. Any ComponentCallbacks class is accessible for the Koin extensions.
You gain access for the Kotlin extensions:
by inject()- lazy evaluated instance from Koin containerget()- eager fetch instance from Koin container
We can declare a property as lazy injected:
module {
// definition of Presenter
factory { Presenter() }
}
class DetailActivity : AppCompatActivity() {
// Lazy inject Presenter
override val presenter : Presenter by inject()
override fun onCreate(savedInstanceState: Bundle?) {
//...
}
}
Or we can just directly get an instance:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Retrieve a Presenter instance
val presenter : Presenter = get()
}
if your class doesn't have extensions, just implement the KoinComponent interface in it to inject() or get() an instance from another class.
Using the Android Context in a Definition
Once your Application class configures Koin you can use the androidContext function to inject Android Context so that it can be resolved later when you need it in modules:
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
// inject Android context
androidContext(this@MainApplication)
// ...
}
}
}
In your definitions, The androidContext() & androidApplication() functions allows you to get the Context instance in a Koin module, to help you simply write expression that requires the Application instance.
val appModule = module {
// create a Presenter instance with injection of R.string.mystring resources from Android
factory {
MyPresenter(androidContext().resources.getString(R.string.mystring))
}
}
Android Scope & Android Context resolution
While you have a scope that is binding the Context type, you may need to resolve the Context but from different level.
Let's take a config:
class MyPresenter(val context : Context)
startKoin {
androidContext(context)
modules(
module {
scope<MyActivity> {
scoped { MyPresenter( <get() ???> ) }
}
}
)
}
To resolve the right type in MyPresenter, use the following:
get()will resolve closestContextdefinition, here it will be the source scopeMyActivityandroidContext()will also resolve closestContextdefinition, here it will be the source scopeMyActivityandroidApplication()will also resolveApplicationdefinition, here it will be the source scopecontextobject defined in Koin setup