How to use Koin in multiple module?

How to use Koin in multiple module?

koin override module
koin-test
koin inject fragment
koin viewmodel
koin sharedpreferences
mvp with koin
koin getproperty
koin get android

There are two modules in my android project, app module and lib module.

Both these two modules need Koin for D.I., so I call startKoin in MyApplication class in app module, and IninKointContentProvider in lib module as below.

// app module
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin(this, modules1)
    }
}

// lib module
class InitKoinContentProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        startKoin(context.applicationContext, modules2)
        return true
    }
}

Then app crashed and shown this message

Caused by: org.koin.error.BeanOverrideException: Try to override definition with Single [class='android.content.Context'], but override is not allowed. Use 'override' option in your definition or module.

I guess startKoin can be called only one time.

The solution I found is merging two koin modules then calling startKoin in MyApplication, but I don't like it. Lib module may be imported by other android project which doesn't use koin, in that case, I think calling startKoin in InitKoinContentProvider is better.

Any solution for this problem?? Thanks!


By design startKoin is meant to be called from the Application class. You can provide a parameter in the lib whether to call startKoin or not. But I doubt that including such things as Koin in libs is a good practice. What if an application already includes Koin, but of different version?

Setting Up Android Modules with Koin - Better Programming, Since then, I've wondered how Koin would work for a multi-module need for the activity to access to the Koin context through the application. Can you provide some hint (or maybe example or sample) how to proper use Koin in project which use modules to divide into layers according to clean arch. So the dependences between modules (layer) should be: appPresentation depends on do


I found the best solution inspired by @laalto's answer, thanks!

Upgrade to koin 2.0, then use KoinApplication and customized KoinComponent to create a isolated koin context, it can let lib module using koin without any initializing call by app module, still start koin in ContentProvider. The whole code may like below.

// app module
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin {
            androidContext(this@MyApplication)
            modules(module{
                viewModel { MainViewModel() }
            })
        }
    }
}

class MainActivity: AppCompactActivity() {
    private val viewModel: MainViewModel by viewModel()
}



// lib module
internal object MyKoinContext {
    lateinit var koinApplication: KoinApplication
}

interface MyKoinComponent : KoinComponent {
    override fun getKoin(): Koin {
        return MyKoinContext.koinApplication.koin
    }
}

class InitKoinContentProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        MyKoinContext.koinApplication = koinApplication {
            androidContext(context.applicationContext)
            modules(module{
                viewModel { FooViewModel() }
            })
        }
        return true
    }
}

class FooActivity: AppCompactActivity(), MyKoinComponent {
    private val viewModel: FooViewModel by viewModel()
}

Ref: https://insert-koin.io/docs/2.0/documentation/reference/index.html#_koin_context_isolation

How to use Koin in multiple module?, I found the best solution inspired by @laalto's answer, thanks! Upgrade to koin 2.0, then use KoinApplication and customized KoinComponent  Koin allows late init module definition load so libraries/features can use this quite easily. Just call the method loadKoinModules on your library and call that method inside your app’s onCreate. Remember, all of the modules (where you define the components) are injected lazily by default.


To init extra koin modules on other project modules and get no duplicate loading issues (e.g. pressing home, than coming back to the activity), go to your module declaration file:

val myModule = module {
    single { MyRepository(get()) }
    viewModel { MyViewModel(get()) }
}

private val loadKoinModules by lazy {
    loadKoinModules(myModule)
}

fun inject() = loadKoinModules

Then on your view:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    inject()
}

Koin in Android Feature Modules Project, Koin, a Dependency Injection framework, in my Multi-Module Feature module definition load so libraries/features can use this quite easily. As you can see the above code creates a new koin module, and here are some important entities. Creates a new koin module using the module {} DSL. The single{} DSL depicts a singleton instance that is unique across the application. Now everything inside single {} will be initialized only once and in our case the OkHttpClient instance.


In your library modules, use loadKoinModules() to load the module-specific koin modules. Docs.

You need to have run startKoin() prior to that, so the init order with content providers can be a little tricky.

Multi-module clean architecture project: make Koin setup reflect , kt containing everything that module provides (Koin). database provides an implementation of the repository, service provides the use cases, app provides the  In Koin, you can use declareMock for those injected objects. It’s good practice to use descriptive names for your methods. Remember that you can use `` to enclose a name with whitespaces. argumentCaptor allows you to grab a value or variable and use it later with any Mockito expression. This is required when using Koin.


TL;DR Use single/factory methods with override param set to true when providing your dependencies that are overriding those provided by the modules loaded before.

single<Manager>(override = true) { TestManager() }

I have faced a similar issue when I tried to override one of the dependencies for UI test purposes. When I setup in Application.onCreate():

startKoin {
   module {
       single { Printer() }
   }
}

and then in before method of test:

loadKoinModules(module {
    single<Printer> { TestPrinter() }
})

I get a Runtime exception during the test: org.koin.core.error.DefinitionOverrideException: Already existing definition or try to override an existing one

And the solution is to show Koin that you are intentionally overriding that dependency by using override param of single function like that:

loadKoinModules(module {
    single<Printer>(override = true) { TestPrinter() }
})

How to use koin in multi-module android project (clean arch)?, Can you provide some hint (or maybe example or sample) how to proper use Koin in project which use modules to divide into layers according to clean arch. This version of Koin is used for Koin with ViewModel, there are some other dependencies to use Koin, But we want to use it with MVVM. After adding Koin dependency we can implement our first module, just like Dagger we can implement every module in a separate file, but because of code simplicity, I decided to implement all modules in a file. you can separate it later.


Using Koin in multi-module Android Project – Onooks, I've a multi-module project & I'm facing some weird issues setting up Koin DI. My project has following modules: app , library . I've declared an  Talking about Koin Articles. Dagger is dead. Long live Koin; Testing a Koin application with KotlinTest; Ready for Koin 2.0; Migration from Dagger2 to Koin; From Dagger to Koin, a step by step migration guide; Koin in Feature Modules Project; A brief look at Koin on Android; Bye bye Dagger; Testing with Koin; Painless Android testing with Room


insert-koin.io · a smart Kotlin dependency injection framework, Written in pure Kotlin using functional resolution only: no proxy, no code it val myModule = module { single { Controller(get()) } single { BusinessService() } }  The join() method is a string method and returns a string in which the elements of sequence have been joined by str separator. Syntax: string_name.join(iterable) string_name: It is the name of string in which joined elements of iterable will be stored.


Minimalist Dagger for multi-modules, How to make Dagger as simple as Koin, even with multiple modules. In the previous article, we've defined the minimum set of tools to use DI  os.path module is sub-module of OS module in Python used for common pathname manipulation. os.path.join() method in Python join one or more path components intelligently. This method concatenates various path components with exactly one directory separator (‘/’) following each non-empty part except the last path component.