{"id":13873,"date":"2018-10-12T09:31:45","date_gmt":"2018-10-12T07:31:45","guid":{"rendered":"https:\/\/www.inovex.de\/blog\/?p=13873"},"modified":"2025-05-26T07:30:02","modified_gmt":"2025-05-26T05:30:02","slug":"five-reasons-why-you-should-use-koin-in-your-next-android-project","status":"publish","type":"post","link":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/","title":{"rendered":"Five Reasons Why You Should Use Koin in Your Next Android Project"},"content":{"rendered":"<p>For many years now, there was basically only one dependency injection library used in Android app projects: <a href=\"https:\/\/google.github.io\/dagger\/\">Dagger (2)<\/a>. While Dagger is offering all the features you could ask for and the API has improved a lot with the update from version 1 to 2, it is still quite tedious to set up. Plus\u2014at least for me\u2014it never felt like a very simple and elegant way of satisfying my dependency injection needs. Enter Koin.<!--more--><\/p>\n<p>With Kotlin gaining more and more popularity (especially among Android developers), a new option for dependency injection has risen: <a href=\"https:\/\/insert-koin.io\/\">Koin<\/a>. Koin has existed for a while now, but the first stable version was released quite recently.<\/p>\n<p><em>Disclaimer:<\/em> Koin may be used for all kinds of applications, but this article&#8217;s focus is on Android app projects (for which Koin offers several bonus features\u2014as described below).<\/p>\n<p>In order to try Koin for myself, I have forked the <a href=\"https:\/\/github.com\/googlesamples\/android-architecture\/tree\/todo-mvp-kotlin\">Kotlin MVP implementation<\/a> of the famous ToDo App from Google&#8217;s Android Architecture Samples and integrated Koin in order to provide the dependencies. The resulting source code can be found <a href=\"https:\/\/github.com\/jschamburger\/android-architecture\/tree\/todo-mvp-kotlin-koin\">here<\/a>. Note that the author of Koin has done <a href=\"https:\/\/github.com\/Ekito\/android-architecture\/tree\/dev-todo-mvp-kotlin-koin\">something very similar<\/a> a couple of months ago, but since then, Koin has changed a bit plus I wanted to try the transition for myself.<\/p>\n<p>Koin can make your life quite a bit easier, especially if you&#8217;re already using Kotlin. So, let&#8217;s take a look at the five reasons to use Koin:<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\"><\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#Koin-is-Easy-to-Set-up\" >Koin is Easy to Set up<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#Kotlin-Features%E2%80%94Elegant-DSL-and-Delegated-Properties\" >Kotlin Features\u2014Elegant DSL and Delegated Properties<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#Android-Features\" >Android Features<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#Testing\" >Testing<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#Logging\" >Logging<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Koin-is-Easy-to-Set-up\"><\/span>Koin is Easy to Set up<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Getting started with Koin could hardly be easier (see\u00a0Getting Started for Android). All you have to do is:<\/p>\n<ol>\n<li>Add the dependency in your build.gradle:\n<pre class=\"lang:default decode:true \">implementation \"org.koin:koin-android:1.0.1\"<\/pre>\n<\/li>\n<li>Create the first module:\n<pre class=\"lang:default decode:true\">val repositoryModule = module {\r\n\r\n    single { ToDoDatabase.getInstance(androidContext()) }\r\n\r\n}\r\n\r\nval appModules = listOf(repositoryModule)<\/pre>\n<p>(Note that the Android Context is directly usable as a parameter through Koin&#8217;s Android extension)<\/li>\n<li>Start Koin in your Application class (which needs to be set up in the AndroidManifest.xml, of course):\n<pre class=\"lang:default decode:true\">class ToDoApplication : Application() {\r\n\r\n    override fun onCreate() {\r\n\r\n        super.onCreate()\r\n\r\n        startKoin(this, appModules)\r\n\r\n    }\r\n\r\n}<\/pre>\n<\/li>\n<li>Start injecting:\n<pre class=\"lang:default decode:true \">class TasksActivity : AppCompatActivity() {\r\n\r\n    val todoDatabase by inject&lt;ToDoDatabase&gt;()\r\n\r\n}<\/pre>\n<\/li>\n<\/ol>\n<p>That&#8217;s it. Now you can already use the database in your activity.<\/p>\n<p>Of course, you actually might prefer applying a pattern like MVP or MVVM to keep stuff like database transactions out of your Android activity\/fragment\/service etc. classes. In case you want to use a Koin-provided dependency in a non-Android class (to be specific, any class not implementing <a href=\"https:\/\/developer.android.com\/reference\/android\/content\/ComponentCallbacks\">ComponentCallbacks<\/a>), there&#8217;s a small extra step: implement the interface <span class=\"lang:default decode:true crayon-inline\">KoinComponent<\/span>\u00a0to get access to functions like <span class=\"lang:default decode:true crayon-inline \">inject()<\/span>\u00a0:<\/p>\n<pre class=\"lang:default decode:true\">class TasksPresenter : KoinComponent {\r\n\r\n    val todoDatabase by inject&lt;ToDoDatabase&gt;()\r\n\r\n}<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Kotlin-Features%E2%80%94Elegant-DSL-and-Delegated-Properties\"><\/span>Kotlin Features\u2014Elegant DSL and Delegated Properties<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>As you may have seen above, Koin uses its own DSL instead of annotations and code generation (like Dagger). Here, Kotlin&#8217;s language features really shine:<\/p>\n<pre class=\"lang:default decode:true\">val appModule = module {\r\n\r\n    single { ToDoDatabase.getInstance(androidContext()) }\r\n\r\n    factory { TasksFragment() }\r\n\r\n    factory&lt;TasksContract.Presenter&gt; { TasksPresenter(get()) }\r\n\r\n}<\/pre>\n<p>Basically, there are two ways of creating instances\u2014<span class=\"lang:default decode:true crayon-inline \">single<\/span>\u00a0 creates singletons (like\u00a0<span class=\"lang:default decode:true crayon-inline \">@Singleton<\/span>\u00a0in Dagger) while\u00a0<span class=\"lang:default decode:true crayon-inline \">factory<\/span>\u00a0creates a new instance every time an object of the respective class is injected. In order to match another types, both <span class=\"lang:default decode:true crayon-inline \">single<\/span>\u00a0 and <span class=\"lang:default decode:true crayon-inline \">factory<\/span>\u00a0 can use type attributes (there are other ways of dealing with generics\u00a0as well).<\/p>\n<p>In the example, the <span class=\"lang:default decode:true crayon-inline \">TasksPresenter<\/span>\u00a0&#8217;s constructor would take one parameter of type <span class=\"lang:default decode:true crayon-inline \">ToDoDatabase<\/span>\u00a0. Since we have defined a <span class=\"lang:default decode:true crayon-inline \">single<\/span>\u00a0 for <span class=\"lang:default decode:true crayon-inline \">ToDoDatabase<\/span>\u00a0 above, this parameter can easily be resolved by using the <span class=\"lang:default decode:true crayon-inline \">get()<\/span>\u00a0 function.<\/p>\n<p>To me, this elegant way of defining modules is definitely an improvement over code generation\u2014having to hit \u201cbuild\u201c before being able to use a newly created module\/component can become quite tedious in large projects. Using delegated properties for injection feels like a very natural thing to do in Kotlin. By the way, there are two ways of providing the type: via a type parameter or via an explicit type definition:<\/p>\n<pre class=\"lang:default decode:true\">val todoDatabase by inject&lt;ToDoDatabase&gt;()\r\n\r\nval anotherTodoDatabase : ToDoDatabase by inject()<\/pre>\n<p>One thing to mention here: <span class=\"lang:default decode:true crayon-inline \">inject()<\/span>\u00a0 is lazy (unless you configure your module or dependency differently)\u2014which is typically what I want when injecting dependencies\u2014while <span class=\"lang:default decode:true crayon-inline \">get()<\/span>\u00a0is eager.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Android-Features\"><\/span>Android Features<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>As mentioned above, the Android context is directly available in modules via an extension function. In addition to this, Koin provides several features and quite a bit of documentation especially for Android apps:<\/p>\n<ul>\n<li><strong>Scopes<\/strong>In Android, many dependencies typically need to be available during the lifetime of Android components like activities or fragments. Just creating new instances of dependencies via\u00a0<span class=\"lang:default decode:true crayon-inline \">factory<\/span>\u00a0 may be problematic since this can cause memory leaks (e.g. if a presenter keeps a reference to an Android view\/fragment). To avoid that, Koin offers scopes that link a dependency&#8217;s availability to the lifecycle of an Android component.\n<p>To use scopes, you need to include a separate module (note that there is another one for AndroidX):<\/p>\n<pre class=\"lang:default decode:true\">implementation \"org.koin:koin-android-scope:1.0.1\"<\/pre>\n<p>Defining dependencies using scopes is just as easy as using <span class=\"lang:default decode:true crayon-inline \">single<\/span>\u00a0 or <span class=\"lang:default decode:true crayon-inline \">factory<\/span>\u00a0:<\/p>\n<pre class=\"lang:default decode:true\">val appModule = module {\r\n\r\n    scope(\"TaskDetailActivity\")  { TaskDetailFragment() }\r\n\r\n    scope&lt;TaskDetailContract.Presenter&gt;(\"TaskDetailActivity\")  { TaskDetailPresenter(getProperty(Properties.EXTRA_TASK_ID)) }\r\n\r\n}<\/pre>\n<p>Now both dependencies are available in the scope called \u201cTaskDetailActivity\u201c &#8211; all that is left to do is to bind this scope to the activity&#8217;s lifecycle:<\/p>\n<pre class=\"lang:default decode:true\">class TaskDetailActivity : AppCompatActivity() {\r\n\r\n    private val taskDetailFragment: TaskDetailFragment by inject()\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n\r\n        super.onCreate(savedInstanceState)\r\n\r\n        setContentView(R.layout.taskdetail_act)\r\n\r\n        bindScope(getOrCreateScope(\"TaskDetailActivity\"))\r\n\r\n    }\r\n\r\n}<\/pre>\n<p>That&#8217;s it. Now the dependencies will only exist as long as the activity.<\/li>\n<li><strong><strong>Architecture Components and ViewModel<\/strong><\/strong>&nbsp;\n<p>Koin offers another module for using ViewModels:<\/p>\n<pre class=\"lang:default decode:true\">implementation \"org.koin:koin-android-viewmodel:1.0.1\"<\/pre>\n<p>While this sample is using MVP we can also easily inject dependencies in our ViewModels.<\/p>\n<p>All you need is a ViewModel with a dependency like this<\/p>\n<pre class=\"lang:default decode:true\">class TaskDetailViewModel(private val taskRepository: TaskRepository) {}<\/pre>\n<p>and this line in your module setup.<\/p>\n<pre class=\"lang:default decode:true \">viewModel { TaskDetailViewModel(get()) }<\/pre>\n<p>Now you can use your ViewModel in your view like this:<\/p>\n<pre class=\"lang:default decode:true \">override fun onCreate(savedInstanceState: Bundle?) {\r\n\r\n    super.onCreate(savedInstanceState)\r\n\r\n    setContentView(R.layout.activity_task_detail)\r\n\r\n    viewModel = getViewModel()\r\n\r\n}<\/pre>\n<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Testing\"><\/span>Testing<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>When testing your application, you might want to replace some dependencies with mock instances simulating whatever behavior you need in your tests\u2014this is one of the main advantages of using dependency injection, after all. You might have guessed it\u2014Koin provides a module for testing.<\/p>\n<pre class=\"lang:default decode:true\">testCompile 'org.koin:koin-test:1.0.1'<\/pre>\n<p>Then, all you have to do is extend KoinTest and start injecting:<\/p>\n<pre class=\"lang:default decode:true \">class TasksPresenterKoinTest : KoinTest {\r\n\r\n    val presenter: TasksContract.Presenter by inject()\r\n\r\n    @Before\r\n\r\n    fun setUp() {\r\n\r\n        startKoin(appModules)\r\n\r\n    }\r\n\r\n    @After\r\n\r\n    fun tearDown() {\r\n\r\n        stopKoin()\r\n\r\n    }\r\n\r\n}<\/pre>\n<p>Of course, you can exchange modules easily in <span class=\"lang:default decode:true crayon-inline \">startKoin()<\/span>\u00a0; but if you want to mock only some classes, Koin has you covered:<\/p>\n<pre class=\"lang:default decode:true\">@Test\r\n\r\n    fun showLoadingIndicatorWhileTasksAreRefreshed() {\r\n\r\n        \/\/ given a repository and a view\r\n\r\n        declareMock&lt;TasksRepository&gt;()\r\n\r\n        declareMock&lt;TasksContract.View&gt;()\r\n\r\n        val mockRepository = get&lt;TasksRepository&gt;()\r\n\r\n        val mockView = get&lt;TasksContract.View&gt;()\r\n\r\n        presenter.view = mockView\r\n\r\n        \/\/ when tasks are loaded\r\n\r\n        presenter.loadTasks(true)\r\n\r\n        \/\/ then loading indicator is shown and tasks are refreshed\r\n\r\n        verify(mockView).setLoadingIndicator(true)\r\n\r\n        verify(mockRepository).refreshTasks()\r\n\r\n    }<\/pre>\n<p>The function <span class=\"lang:default decode:true crayon-inline \">declareMock()<\/span>\u00a0creates a <a href=\"https:\/\/site.mockito.org\/\">Mockito<\/a> mock of the respective dependency. In the test above,\u00a0 the presenter uses a repository and a view, both of which shall be mocked for this case. After this is set up, we can call the function we want to test and verify the expected outcomes. More sophisticated setup (like having the repository return specific tasks) and verification (like capturing and checking arguments) can easily be added using the established Mockito APIs.<\/p>\n<p>In case your dependency tree grows more complex, you might also want to check your modules.<\/p>\n<p>Just like the other Koin features described above, unit testing was very easy to set up and I liked the neat possibility for creating mocks.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Logging\"><\/span>Logging<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Last but not least, Koin logs a lot of information\u2014the modules and dependency declarations as well as information about the creation of dependencies (since they are typically injected lazily) and their transitive dependencies.<\/p>\n<pre class=\"lang:default decode:true\">I\/KOIN: [context] create\r\n\r\nI\/KOIN: [module] declare Single [name='ToDoDatabase',class='com.example.android.architecture.blueprints.todoapp.data.source.local.ToDoDatabase']\r\n\r\n    [module] declare Single [name='TasksDao',class='com.example.android.architecture.blueprints.todoapp.data.source.local.TasksDao']\r\n\r\nI\/KOIN: [module] declare Single [name='remoteDataSource',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource']\r\n\r\n    [module] declare Single [name='localDataSource',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource']\r\n\r\n    [module] declare Single [name='TasksRepository',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository']\r\n\r\nI\/KOIN: [module] declare Factory [name='TasksFragment',class='com.example.android.architecture.blueprints.todoapp.tasks.TasksFragment']\r\n\r\n    [module] declare Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter']\r\n\r\nI\/KOIN: [module] declare Factory [name='TaskDetailFragment',class='com.example.android.architecture.blueprints.todoapp.taskdetail.TaskDetailFragment']\r\n\r\n    [module] declare Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.taskdetail.TaskDetailContract.Presenter']\r\n\r\n    [module] declare Factory [name='AddEditTaskFragment',class='com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskFragment']\r\n\r\n    [module] declare Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskContract.Presenter']\r\n\r\nI\/KOIN: [module] declare Factory [name='StatisticsFragment',class='com.example.android.architecture.blueprints.todoapp.statistics.StatisticsFragment']\r\n\r\n    [module] declare Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.statistics.StatisticsContract.Presenter']\r\n\r\n    [modules] loaded 13 definitions\r\n\r\nD\/KOIN: [modules] loaded in 12.056094 ms\r\n\r\nI\/KOIN: [init] declare Android Context\r\n\r\n    [module] declare Single [class='android.content.Context']\r\n\r\nI\/KOIN: [module] declare Single [class='android.app.Application']\r\n\r\nI\/KOIN: +-- 'com.example.android.architecture.blueprints.todoapp.tasks.TasksFragment'\r\n\r\nD\/KOIN: |-- [Factory [name='TasksFragment',class='com.example.android.architecture.blueprints.todoapp.tasks.TasksFragment']]\r\n\r\nD\/KOIN: |-- TasksFragment{a76f444}\r\n\r\nI\/KOIN: \\-- (*) Created\r\n\r\nD\/KOIN: !-- [com.example.android.architecture.blueprints.todoapp.tasks.TasksFragment] resolved in 9.344479 ms\r\n\r\nI\/KOIN: +-- 'com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter'\r\n\r\nD\/KOIN: |-- [Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter']]\r\n\r\nD\/KOIN: |-- com.example.android.architecture.blueprints.todoapp.tasks.TasksPresenter@345ceae\r\n\r\nI\/KOIN: \\-- (*) Created\r\n\r\nD\/KOIN: !-- [com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter] resolved in 2.499323 ms\r\n\r\nI\/KOIN: +-- 'com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository'\r\n\r\nD\/KOIN: |-- [Single [name='TasksRepository',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository']]\r\n\r\nI\/KOIN: |\t+-- 'com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource'\r\n\r\nD\/KOIN: |\t|-- [Single [name='remoteDataSource',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource']]\r\n\r\nD\/KOIN: |\t|-- com.example.android.architecture.blueprints.todoapp.data.FakeTasksRemoteDataSource@246344f\r\n\r\nI\/KOIN: |\t\\-- (*) Created\r\n\r\nD\/KOIN: |\t!-- [com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource] resolved in 2.057084 ms\r\n\r\nI\/KOIN: |\t+-- 'com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource'\r\n\r\nD\/KOIN: |\t|-- [Single [name='localDataSource',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource']]\r\n\r\nI\/KOIN: |\t|\t+-- 'com.example.android.architecture.blueprints.todoapp.data.source.local.TasksDao'\r\n\r\nD\/KOIN: |\t|\t|-- [Single [name='TasksDao',class='com.example.android.architecture.blueprints.todoapp.data.source.local.TasksDao']]\r\n\r\nI\/KOIN: |\t|\t|\t+-- 'com.example.android.architecture.blueprints.todoapp.data.source.local.ToDoDatabase'\r\n\r\nD\/KOIN: |\t|\t|\t|-- [Single [name='ToDoDatabase',class='com.example.android.architecture.blueprints.todoapp.data.source.local.ToDoDatabase']]\r\n\r\nI\/KOIN: |\t|\t|\t|\t+-- 'android.content.Context'\r\n\r\nD\/KOIN: |\t|\t|\t|\t|-- [Single [class='android.content.Context']]\r\n\r\n    |\t|\t|\t|\t|-- com.example.android.architecture.blueprints.todoapp.ToDoApplication@fee87dc\r\n\r\nI\/KOIN: |\t|\t|\t|\t\\-- (*) Created\r\n\r\nD\/KOIN: |\t|\t|\t|\t!-- [android.content.Context] resolved in 0.868438 ms\r\n\r\nD\/KOIN: |\t|\t|\t|-- com.example.android.architecture.blueprints.todoapp.data.source.local.ToDoDatabase_Impl@61d10e5\r\n\r\nI\/KOIN: |\t|\t|\t\\-- (*) Created\r\n\r\nD\/KOIN: |\t|\t|\t!-- [com.example.android.architecture.blueprints.todoapp.data.source.local.ToDoDatabase] resolved in 7.766406 ms\r\n\r\nD\/KOIN: |\t|\t|-- com.example.android.architecture.blueprints.todoapp.data.source.local.TasksDao_Impl@ba427ba\r\n\r\nI\/KOIN: |\t|\t\\-- (*) Created\r\n\r\nD\/KOIN: |\t|\t!-- [com.example.android.architecture.blueprints.todoapp.data.source.local.TasksDao] resolved in 10.958333 ms\r\n\r\n    |\t|-- com.example.android.architecture.blueprints.todoapp.data.source.local.TasksLocalDataSource@cdbc66b\r\n\r\nI\/KOIN: |\t\\-- (*) Created\r\n\r\nD\/KOIN: |\t!-- [com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource] resolved in 14.813802 ms\r\n\r\n    |-- com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository@1ca45c8\r\n\r\nI\/KOIN: \\-- (*) Created\r\n\r\nD\/KOIN: !-- [com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository] resolved in 20.30526 ms<\/pre>\n<p>This may sound simple, but it can be extremely helpful as the dependency tree grows more complex\u2014especially with multiple build variants replacing modules or (of course!) tests:<\/p>\n<pre class=\"lang:default decode:true \">2018-09-19 15:21:00:675 (KOIN)::[i] [PrintLogger] display debug = false\r\n\r\n2018-09-19 15:21:00:704 (KOIN)::[i] [context] create\r\n\r\n2018-09-19 15:21:00:771 (KOIN)::[i] [module] declare Single [name='ToDoDatabase',class='com.example.android.architecture.blueprints.todoapp.data.source.local.ToDoDatabase']\r\n\r\n2018-09-19 15:21:00:772 (KOIN)::[i] [module] declare Single [name='TasksDao',class='com.example.android.architecture.blueprints.todoapp.data.source.local.TasksDao']\r\n\r\n2018-09-19 15:21:00:772 (KOIN)::[i] [module] declare Single [name='remoteDataSource',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource']\r\n\r\n2018-09-19 15:21:00:772 (KOIN)::[i] [module] declare Single [name='localDataSource',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksDataSource']\r\n\r\n2018-09-19 15:21:00:772 (KOIN)::[i] [module] declare Single [name='TasksRepository',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository']\r\n\r\n2018-09-19 15:21:00:818 (KOIN)::[i] [module] declare Factory [name='TasksFragment',class='com.example.android.architecture.blueprints.todoapp.tasks.TasksFragment']\r\n\r\n2018-09-19 15:21:00:819 (KOIN)::[i] [module] declare Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter']\r\n\r\n2018-09-19 15:21:00:819 (KOIN)::[i] [module] declare Scope [name='TaskDetailFragment',class='com.example.android.architecture.blueprints.todoapp.taskdetail.TaskDetailFragment']\r\n\r\n2018-09-19 15:21:00:821 (KOIN)::[i] [module] declare Scope [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.taskdetail.TaskDetailContract.Presenter']\r\n\r\n2018-09-19 15:21:00:821 (KOIN)::[i] [module] declare Factory [name='AddEditTaskFragment',class='com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskFragment']\r\n\r\n2018-09-19 15:21:00:822 (KOIN)::[i] [module] declare Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskContract.Presenter']\r\n\r\n2018-09-19 15:21:00:824 (KOIN)::[i] [module] declare Factory [name='StatisticsFragment',class='com.example.android.architecture.blueprints.todoapp.statistics.StatisticsFragment']\r\n\r\n2018-09-19 15:21:00:826 (KOIN)::[i] [module] declare Factory [name='Presenter',class='com.example.android.architecture.blueprints.todoapp.statistics.StatisticsContract.Presenter']\r\n\r\n2018-09-19 15:21:00:826 (KOIN)::[i] [modules] loaded 13 definitions\r\n\r\n2018-09-19 15:21:00:889 (KOIN)::[i] [mock] declare mock for class com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository\r\n\r\n2018-09-19 15:21:00:894 (KOIN)::[i] [module] override Single [name='TasksRepository',class='com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository']\r\n\r\n2018-09-19 15:21:00:895 (KOIN)::[i] [modules] loaded 13 definitions\r\n\r\n2018-09-19 15:21:00:896 (KOIN)::[i] [mock] declare mock for interface com.example.android.architecture.blueprints.todoapp.tasks.TasksContract$View\r\n\r\n2018-09-19 15:21:00:899 (KOIN)::[i] [module] declare Single [name='View',class='com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.View']\r\n\r\n2018-09-19 15:21:00:899 (KOIN)::[i] [modules] loaded 14 definitions\r\n\r\n2018-09-19 15:21:00:932 (KOIN)::[i] +-- 'com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository'\r\n\r\n2018-09-19 15:21:02:667 (KOIN)::[i] \\-- (*) Created\r\n\r\n2018-09-19 15:21:02:667 (KOIN)::[i] +-- 'com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.View'\r\n\r\n2018-09-19 15:21:02:982 (KOIN)::[i] \\-- (*) Created\r\n\r\n2018-09-19 15:21:02:982 (KOIN)::[i] +-- 'com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter'\r\n\r\n2018-09-19 15:21:02:985 (KOIN)::[i] \\-- (*) Created\r\n\r\n2018-09-19 15:21:02:992 (KOIN)::[i] +-- 'com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository'\r\n\r\n2018-09-19 15:21:03:015 (KOIN)::[i] [Close] Closing Koin context<\/pre>\n<p>Note the lines about mock declarations.<\/p>\n<p>For everyone who has at some point struggled to understand the relationship between injected dependencies (which is probably just about anyone who has used dependency injection in a larger project), this should help a lot. Of course, Koin includes many features I didn&#8217;t mention above (the feature set is quite impressive for a 1.0), but as a new user, those were the parts I enjoyed the most when working with Koin.<\/p>\n<h2 class=\"p1\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Most of all, Koin is easy to use and integrates well in a Kotlin Android project (btw, it may be used for Java projects as well). With the 1.0.0 only released a short while ago, the project feels very mature and stable; also the documentation is pretty extensive.<\/p>\n<p>Compared to Dagger 2, using Koin felt a lot easier, more fun and so far I haven&#8217;t encountered any missing features. So go ahead and try it!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For many years now, there was basically only one dependency injection library used in Android app projects: Dagger (2). While Dagger is offering all the features you could ask for and the API has improved a lot with the update from version 1 to 2, it is still quite tedious to set up. Plus\u2014at least [&hellip;]<\/p>\n","protected":false},"author":242,"featured_media":14149,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"ep_exclude_from_search":false,"footnotes":""},"tags":[510],"service":[],"coauthors":[{"id":242,"display_name":"Johannes Schamburger","user_nicename":"jschamburger"}],"class_list":["post-13873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-apps-2"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Five Reasons Why You Should Use Koin in Your Next Android Project<\/title>\n<meta name=\"description\" content=\"With Kotlin gaining more and more popularity (especially among Android developers), a new option for dependency injection has risen: Koin. Here are 5 reasons why you should rely on Koin in your new Android Projects!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Five Reasons Why You Should Use Koin in Your Next Android Project\" \/>\n<meta property=\"og:description\" content=\"With Kotlin gaining more and more popularity (especially among Android developers), a new option for dependency injection has risen: Koin. Here are 5 reasons why you should rely on Koin in your new Android Projects!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/\" \/>\n<meta property=\"og:site_name\" content=\"inovex GmbH\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/inovexde\" \/>\n<meta property=\"article:published_time\" content=\"2018-10-12T07:31:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-26T05:30:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Johannes Schamburger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons-1024x576.png\" \/>\n<meta name=\"twitter:creator\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:site\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Johannes Schamburger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"9\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Johannes Schamburger\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/\"},\"author\":{\"name\":\"Johannes Schamburger\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/person\\\/7d3af07f106f0e7f1d1414f7e4b8b44c\"},\"headline\":\"Five Reasons Why You Should Use Koin in Your Next Android Project\",\"datePublished\":\"2018-10-12T07:31:45+00:00\",\"dateModified\":\"2025-05-26T05:30:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/\"},\"wordCount\":1274,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/koin-kotlin-5-reasons.png\",\"keywords\":[\"Apps\"],\"articleSection\":[\"Applications\",\"English Content\",\"General\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/\",\"name\":\"Five Reasons Why You Should Use Koin in Your Next Android Project\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/koin-kotlin-5-reasons.png\",\"datePublished\":\"2018-10-12T07:31:45+00:00\",\"dateModified\":\"2025-05-26T05:30:02+00:00\",\"description\":\"With Kotlin gaining more and more popularity (especially among Android developers), a new option for dependency injection has risen: Koin. Here are 5 reasons why you should rely on Koin in your new Android Projects!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/koin-kotlin-5-reasons.png\",\"contentUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/koin-kotlin-5-reasons.png\",\"width\":1920,\"height\":1080,\"caption\":\"A broken Dagger on a Koin\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/five-reasons-why-you-should-use-koin-in-your-next-android-project\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Five Reasons Why You Should Use Koin in Your Next Android Project\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/\",\"name\":\"inovex GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#organization\",\"name\":\"inovex GmbH\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/inovex-logo-16-9-1.png\",\"contentUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/inovex-logo-16-9-1.png\",\"width\":1921,\"height\":1081,\"caption\":\"inovex GmbH\"},\"image\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/inovexde\",\"https:\\\/\\\/x.com\\\/inovexgmbh\",\"https:\\\/\\\/www.instagram.com\\\/inovexlife\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/inovex\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UC7r66GT14hROB_RQsQBAQUQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/person\\\/7d3af07f106f0e7f1d1414f7e4b8b44c\",\"name\":\"Johannes Schamburger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/IMG_3315_cropped-96x96.jpg54c1cc63e1170525fc8d2bb128512f74\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/IMG_3315_cropped-96x96.jpg\",\"contentUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/IMG_3315_cropped-96x96.jpg\",\"caption\":\"Johannes Schamburger\"},\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/author\\\/jschamburger\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Five Reasons Why You Should Use Koin in Your Next Android Project","description":"With Kotlin gaining more and more popularity (especially among Android developers), a new option for dependency injection has risen: Koin. Here are 5 reasons why you should rely on Koin in your new Android Projects!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/","og_locale":"de_DE","og_type":"article","og_title":"Five Reasons Why You Should Use Koin in Your Next Android Project","og_description":"With Kotlin gaining more and more popularity (especially among Android developers), a new option for dependency injection has risen: Koin. Here are 5 reasons why you should rely on Koin in your new Android Projects!","og_url":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/","og_site_name":"inovex GmbH","article_publisher":"https:\/\/www.facebook.com\/inovexde","article_published_time":"2018-10-12T07:31:45+00:00","article_modified_time":"2025-05-26T05:30:02+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons.png","type":"image\/png"}],"author":"Johannes Schamburger","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons-1024x576.png","twitter_creator":"@inovexgmbh","twitter_site":"@inovexgmbh","twitter_misc":{"Verfasst von":"Johannes Schamburger","Gesch\u00e4tzte Lesezeit":"9\u00a0Minuten","Written by":"Johannes Schamburger"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#article","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/"},"author":{"name":"Johannes Schamburger","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/7d3af07f106f0e7f1d1414f7e4b8b44c"},"headline":"Five Reasons Why You Should Use Koin in Your Next Android Project","datePublished":"2018-10-12T07:31:45+00:00","dateModified":"2025-05-26T05:30:02+00:00","mainEntityOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/"},"wordCount":1274,"commentCount":0,"publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons.png","keywords":["Apps"],"articleSection":["Applications","English Content","General"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/","url":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/","name":"Five Reasons Why You Should Use Koin in Your Next Android Project","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#primaryimage"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons.png","datePublished":"2018-10-12T07:31:45+00:00","dateModified":"2025-05-26T05:30:02+00:00","description":"With Kotlin gaining more and more popularity (especially among Android developers), a new option for dependency injection has risen: Koin. Here are 5 reasons why you should rely on Koin in your new Android Projects!","breadcrumb":{"@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#primaryimage","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2018\/10\/koin-kotlin-5-reasons.png","width":1920,"height":1080,"caption":"A broken Dagger on a Koin"},{"@type":"BreadcrumbList","@id":"https:\/\/www.inovex.de\/de\/blog\/five-reasons-why-you-should-use-koin-in-your-next-android-project\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.inovex.de\/de\/"},{"@type":"ListItem","position":2,"name":"Five Reasons Why You Should Use Koin in Your Next Android Project"}]},{"@type":"WebSite","@id":"https:\/\/www.inovex.de\/de\/#website","url":"https:\/\/www.inovex.de\/de\/","name":"inovex GmbH","description":"","publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.inovex.de\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.inovex.de\/de\/#organization","name":"inovex GmbH","url":"https:\/\/www.inovex.de\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","width":1921,"height":1081,"caption":"inovex GmbH"},"image":{"@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/inovexde","https:\/\/x.com\/inovexgmbh","https:\/\/www.instagram.com\/inovexlife\/","https:\/\/www.linkedin.com\/company\/inovex","https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ"]},{"@type":"Person","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/7d3af07f106f0e7f1d1414f7e4b8b44c","name":"Johannes Schamburger","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/wp-content\/uploads\/IMG_3315_cropped-96x96.jpg54c1cc63e1170525fc8d2bb128512f74","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/IMG_3315_cropped-96x96.jpg","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/IMG_3315_cropped-96x96.jpg","caption":"Johannes Schamburger"},"url":"https:\/\/www.inovex.de\/de\/blog\/author\/jschamburger\/"}]}},"_links":{"self":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/13873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/users\/242"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/comments?post=13873"}],"version-history":[{"count":5,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/13873\/revisions"}],"predecessor-version":[{"id":62435,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/13873\/revisions\/62435"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media\/14149"}],"wp:attachment":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media?parent=13873"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/tags?post=13873"},{"taxonomy":"service","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/service?post=13873"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/coauthors?post=13873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}