Koin DSL
Thanks to the power of Kotlin language, Koin provides a DSL to help your describe your app instead of annotate it or generate code for it. With its Kotlin DSL, Koin offers a smart functional API to achieve to prepare your dependency injection.
Application & Module DSL
Koin offers several keywords to let you describe the elements of a Koin Application:
- Application DSL, to describe the Koin container configuration
- Module DSL, to describe the components that have to be injected
Application DSL
A KoinApplication
instance is a Koin container instance configuration. This will let your configure logging, properties loading and modules.
To build a new KoinApplication
, use the following functions:
koinApplication { }
- create aKoinApplication
container configurationstartKoin { }
- create aKoinApplication
container configuration and register it in theGlobalContext
to allow the use of GlobalContext API
To configure your KoinApplication
instance, you can use any of the following functions :
logger( )
- describe what level and Logger implementation to use (by default use the EmptyLogger)modules( )
- set a list of Koin modules to load in the container (list or vararg list)properties()
- load HashMap properties into Koin containerfileProperties( )
- load properties from given file into Koin containerenvironmentProperties( )
- load properties from OS environment into Koin containercreateEagerInstances()
- create eager instances (Single definitions marked ascreatedAtStart
)
KoinApplication instance: Global vs Local
As you can see above, we can describe a Koin container configuration in 2 ways: koinApplication
or startKoin
function.
koinApplication
describe a Koin container instancestartKoin
describe a Koin container instance and register it in KoinGlobalContext
By registering your container configuration into the GlobalContext
, the global API can use it directly. Any KoinComponent
refers to a Koin
instance. By default we use the one from GlobalContext
.
Check chapters about Custom Koin instance for more information.
Starting Koin
Starting Koin means run a KoinApplication
instance into the GlobalContext
.
To start Koin container with modules, we can just use the startKoin
function like that:
Module DSL
A Koin module gather definitions that you will inject/combine for your application. To create a new module, just use the following function:
module { // module content }
- create a Koin Module
To describe your content in a module, you can use the following functions:
factory { //definition }
- provide a factory bean definitionsingle { //definition }
- provide a singleton bean definition (also aliased asbean
)get()
- resolve a component dependency (also can use name, scope or parameters)bind()
- add type to bind for given bean definitionbinds()
- add types array for given bean definitionscope { // scope group }
- define a logical group forscoped
definitionscoped { //definition }
- provide a bean definition that will exists only in a scope
Note: the named()
function allow you to give a qualifier either by a string, an enum or a type. It is used to name your definitions.
Writing a module
A Koin module is the space to declare all your components. Use the module
function to declare a Koin module:
In this module, you can declare components as described below.
withOptions - DSL Options (since 3.2)
Like for new Constructor DSL definitions, you can specify definition options on "regular" definitions with
the withOptions
operator:
Within this option lambda, you can specify the following options:
named("a_qualifier")
- give a String qualifier to the definitionnamed<MyType>()
- give a Type qualifier to the definitionbind<MyInterface>()
- add type to bind for given bean definitionbinds(arrayOf(...))
- add types array for given bean definitioncreatedAtStart()
- create single instance at Koin start
Module Includes (since 3.2)
A new function includes()
is available in the Module
class, which lets you compose a module by including other modules in an organized and structured way.
The two prominent use cases of the new feature are:
- Split large modules into smaller and more focused ones.
- In modularized projects, it allows you more fine control over a module visibility (see examples below).
How does it work? Let's take some modules, and we include modules in parentModule
:
Notice we do not need to set up all modules explicitly: by including parentModule
, all the modules declared in the includes
will be automatically loaded (childModule1
and childModule2
). In other words, Koin is effectively loading: parentModule
, childModule1
and childModule2
.
An important detail to observe is that you can use includes
to add internal
and private
modules too - that gives you flexibility over what to expose in a modularized project.
info
Module loading is now optimized to flatten all your module graphs and avoid duplicated definitions of modules.
Finally, you can include multiple nested or duplicates modules, and Koin will flatten all the included modules removing duplicates:
Notice that all modules will be included only once: dataModule
, domainModule
, featureModule1
, featureModule2
.