Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Koin share dependencies scoped to nested graph

I'm wondering how to properly scope dependencies with Koin library.

Since Google recommends a single Activity architecture the AndroidX Navigation lib has become a key library to facilitate this by easily swapping Fragments.

A typical modern Android app has multiple features separated in packages and/or Gradle modules.
These feature modules provides a graph that can be used in the root graph as nested graphs. (See picture)

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root_graph"
    app:startDestination="@id/mainFragment">

    <include app:graph="@navigation/nav_graph_feature_a" />
    <include app:graph="@navigation/nav_graph_feature_b" />

    <fragment
        android:id="@+id/mainFragment"
        android:name="com.example.androidx_navigation.MainFragment"
        android:label="MainFragment"
        tools:layout="@layout/fragment_main">
        <action
            android:id="@+id/action_mainFragment_to_featureAFragment1"
            app:destination="@id/nav_graph_feature_a" />
        <action
            android:id="@+id/action_mainFragment_to_featureBFragment1"
            app:destination="@id/nav_graph_feature_b" />
    </fragment>
</navigation>

Koin scoping of feature modules

Following rules should be respected:

  • Every layer represent a scope.
  • Inner layers can inject anything defined in outer layers.
  • Layers that do not have an overlap should not be able to inject each other's dependencies.
  • Leaving a layer should dispose of its dependencies.

More concretely:

  • FeatureA can inject Activity and App dependencies, but not FeatureB dependencies
  • FeatureB can inject Activity and App dependencies, but not FeatureA dependencies

How to achieve this in Koin?

Note that sharing dependencies is not limited to ViewModel only.
I should be able to share any arbitrary class within my scope.

like image 765
timr Avatar asked Dec 24 '20 13:12

timr


1 Answers

Actually, I think you can use loadModule and unLoadModule in your feature Modules and with some layer modules like network uiKit and ... control their needs.

FeatureA can inject Activity and App dependencies, but not FeatureB dependencies

I think this is not reasonable that inject your appModule in the FeatueA, you can have a coreModule and add this in your all modules that needed, also you can find your activity with requireActivity() in your fragmnet for example:D, so the FeatureA never can inject FeatureB dependencies, because they have no access to each other.

like image 62
hamid Mahmoodi Avatar answered Sep 29 '22 09:09

hamid Mahmoodi