Designing Modular Apps - Circular Dependency problem in navigation





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







7















As you know, designing Android app as modules is one of the popular practices nowadays in the Android development world. But this trend comes with some challenges. One of them is Circular Dependency.



For example, I have a navigation module which opens HomeActivity from Home Feature module. Also, I have to open another activity such as ProductListActivity from products module.



Home feature must include navigation module and navigation module should include HomeFeature if i navigate between activities like the following:



val intent = Intent(activity, HomeActivity::class.java)


This'll cause circular dependency problem.



For a fastest solution to figure out this problem is creating intents like the following and build navigation system on this approach.



Intent(Intent.ACTION_VIEW).setClassName(PACKAGE_NAME, className)


So my questions are, what other possible problems we'll face off with this navigation approach? Are there another practises to handle navigation in modular android apps?










share|improve this question































    7















    As you know, designing Android app as modules is one of the popular practices nowadays in the Android development world. But this trend comes with some challenges. One of them is Circular Dependency.



    For example, I have a navigation module which opens HomeActivity from Home Feature module. Also, I have to open another activity such as ProductListActivity from products module.



    Home feature must include navigation module and navigation module should include HomeFeature if i navigate between activities like the following:



    val intent = Intent(activity, HomeActivity::class.java)


    This'll cause circular dependency problem.



    For a fastest solution to figure out this problem is creating intents like the following and build navigation system on this approach.



    Intent(Intent.ACTION_VIEW).setClassName(PACKAGE_NAME, className)


    So my questions are, what other possible problems we'll face off with this navigation approach? Are there another practises to handle navigation in modular android apps?










    share|improve this question



























      7












      7








      7


      2






      As you know, designing Android app as modules is one of the popular practices nowadays in the Android development world. But this trend comes with some challenges. One of them is Circular Dependency.



      For example, I have a navigation module which opens HomeActivity from Home Feature module. Also, I have to open another activity such as ProductListActivity from products module.



      Home feature must include navigation module and navigation module should include HomeFeature if i navigate between activities like the following:



      val intent = Intent(activity, HomeActivity::class.java)


      This'll cause circular dependency problem.



      For a fastest solution to figure out this problem is creating intents like the following and build navigation system on this approach.



      Intent(Intent.ACTION_VIEW).setClassName(PACKAGE_NAME, className)


      So my questions are, what other possible problems we'll face off with this navigation approach? Are there another practises to handle navigation in modular android apps?










      share|improve this question
















      As you know, designing Android app as modules is one of the popular practices nowadays in the Android development world. But this trend comes with some challenges. One of them is Circular Dependency.



      For example, I have a navigation module which opens HomeActivity from Home Feature module. Also, I have to open another activity such as ProductListActivity from products module.



      Home feature must include navigation module and navigation module should include HomeFeature if i navigate between activities like the following:



      val intent = Intent(activity, HomeActivity::class.java)


      This'll cause circular dependency problem.



      For a fastest solution to figure out this problem is creating intents like the following and build navigation system on this approach.



      Intent(Intent.ACTION_VIEW).setClassName(PACKAGE_NAME, className)


      So my questions are, what other possible problems we'll face off with this navigation approach? Are there another practises to handle navigation in modular android apps?







      android






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 4 at 11:21









      Fantômas

      32.9k156491




      32.9k156491










      asked Jan 4 at 10:34









      savepopulationsavepopulation

      8,02543753




      8,02543753
























          2 Answers
          2






          active

          oldest

          votes


















          5














          Here is my solution for stiuation. This enables the use of explicit intents. You can also apply this approach to single activity application with navigation component with a little modification.



          Here is navigation object for module B



          object ModuleBNavigator {

          internal lateinit var navigationImpl: ModuleBContract

          fun setNavigationImpl(navigationImpl: ModuleBContract) {
          this.navigationImpl = navigationImpl
          }

          interface ModuleBContract {
          fun navigateModuleA(self: Activity, bundle: Bundle?)
          }
          }


          And here is module B Activity



          class ModuleBActivity : Activity() {

          companion object {
          private const val BUNDLE = "BUNDLE"
          fun newIntent(context: Context, bundle: Bundle?) = Intent(context, ModuleBActivity::class.java).apply {
          putExtra(BUNDLE, bundle)
          }
          }
          }


          And here is app module class to inject navigation impl to module A navigation object



          class ApplicationModuleApp : Application() {

          // Can also inject with a DI library
          override fun onCreate() {
          super.onCreate()
          ModuleBNavigator.setNavigationImpl(object : ModuleBNavigator.ModuleBContract {
          override fun navigateModuleA(self: Activity, bundle: Bundle?) {
          self.startActivity(ModuleBActivity.newIntent(self, bundle))
          }
          })
          }
          }


          And finally you can navigate from module A -> module B with provided implementation



          class ModuleAActivity : Activity() {

          override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          // ... Some code
          ModuleBNavigator.navigationImpl.navigateModuleA(this, Bundle())
          // .. Some code
          }
          }


          This approact avoids circler dependency and you don't have to use implicit intents anymore.
          Hope this helps.






          share|improve this answer































            1














            For a different approach -actually similar which I mentioned in my question- which implementation belongs to sanogueralorenzo



            Create a loader which laods the module classes



            const val PACKAGE_NAME = "com.example.android"

            private val classMap = mutableMapOf<String, Class<*>>()

            private inline fun <reified T : Any> Any.castOrReturnNull() = this as? T

            internal fun <T> String.loadClassOrReturnNull(): Class<out T>? =
            classMap.getOrPut(this) {
            try {
            Class.forName(this)
            } catch (e: ClassNotFoundException) {
            return null
            }
            }.castOrReturnNull()


            Create a String extension function for loading Intents dynamically.



            private fun intentTo(className: String): Intent =
            Intent(Intent.ACTION_VIEW).setClassName(BuildConfig.PACKAGE_NAME, className)

            internal fun String.loadIntentOrReturnNull(): Intent? =
            try {
            Class.forName(this).run { intentTo(this@loadIntentOrReturnNull) }
            } catch (e: ClassNotFoundException) {
            null
            }


            Create another String extension function for loading Fragments dynamically



            internal fun String.loadFragmentOrReturnNull(): Fragment? =
            try {
            this.loadClassOrReturnNull<Fragment>()?.newInstance()
            } catch (e: ClassNotFoundException) {
            null
            }


            Create an Feature interface for your feature implementations



            interface Feature<T> {
            val dynamicStart: T?
            }


            I assume that you have a Messages feature. Implement your dynamic feature interface



            object Messages : Feature<Fragment> {

            private const val MESSAGES = "$PACKAGE_NAME.messages.presentation.MessagesFragment"

            override val dynamicStart: Fragment?
            get() = MESSAGES.loadFragmentOrReturnNull()

            }


            And finally use it in another module without dependency



             Messages.dynamicStart?.let {
            if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
            .replace(R.id.fl_main, it)
            .commit()
            }
            }





            share|improve this answer
























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54037244%2fdesigning-modular-apps-circular-dependency-problem-in-navigation%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              5














              Here is my solution for stiuation. This enables the use of explicit intents. You can also apply this approach to single activity application with navigation component with a little modification.



              Here is navigation object for module B



              object ModuleBNavigator {

              internal lateinit var navigationImpl: ModuleBContract

              fun setNavigationImpl(navigationImpl: ModuleBContract) {
              this.navigationImpl = navigationImpl
              }

              interface ModuleBContract {
              fun navigateModuleA(self: Activity, bundle: Bundle?)
              }
              }


              And here is module B Activity



              class ModuleBActivity : Activity() {

              companion object {
              private const val BUNDLE = "BUNDLE"
              fun newIntent(context: Context, bundle: Bundle?) = Intent(context, ModuleBActivity::class.java).apply {
              putExtra(BUNDLE, bundle)
              }
              }
              }


              And here is app module class to inject navigation impl to module A navigation object



              class ApplicationModuleApp : Application() {

              // Can also inject with a DI library
              override fun onCreate() {
              super.onCreate()
              ModuleBNavigator.setNavigationImpl(object : ModuleBNavigator.ModuleBContract {
              override fun navigateModuleA(self: Activity, bundle: Bundle?) {
              self.startActivity(ModuleBActivity.newIntent(self, bundle))
              }
              })
              }
              }


              And finally you can navigate from module A -> module B with provided implementation



              class ModuleAActivity : Activity() {

              override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              // ... Some code
              ModuleBNavigator.navigationImpl.navigateModuleA(this, Bundle())
              // .. Some code
              }
              }


              This approact avoids circler dependency and you don't have to use implicit intents anymore.
              Hope this helps.






              share|improve this answer




























                5














                Here is my solution for stiuation. This enables the use of explicit intents. You can also apply this approach to single activity application with navigation component with a little modification.



                Here is navigation object for module B



                object ModuleBNavigator {

                internal lateinit var navigationImpl: ModuleBContract

                fun setNavigationImpl(navigationImpl: ModuleBContract) {
                this.navigationImpl = navigationImpl
                }

                interface ModuleBContract {
                fun navigateModuleA(self: Activity, bundle: Bundle?)
                }
                }


                And here is module B Activity



                class ModuleBActivity : Activity() {

                companion object {
                private const val BUNDLE = "BUNDLE"
                fun newIntent(context: Context, bundle: Bundle?) = Intent(context, ModuleBActivity::class.java).apply {
                putExtra(BUNDLE, bundle)
                }
                }
                }


                And here is app module class to inject navigation impl to module A navigation object



                class ApplicationModuleApp : Application() {

                // Can also inject with a DI library
                override fun onCreate() {
                super.onCreate()
                ModuleBNavigator.setNavigationImpl(object : ModuleBNavigator.ModuleBContract {
                override fun navigateModuleA(self: Activity, bundle: Bundle?) {
                self.startActivity(ModuleBActivity.newIntent(self, bundle))
                }
                })
                }
                }


                And finally you can navigate from module A -> module B with provided implementation



                class ModuleAActivity : Activity() {

                override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                // ... Some code
                ModuleBNavigator.navigationImpl.navigateModuleA(this, Bundle())
                // .. Some code
                }
                }


                This approact avoids circler dependency and you don't have to use implicit intents anymore.
                Hope this helps.






                share|improve this answer


























                  5












                  5








                  5







                  Here is my solution for stiuation. This enables the use of explicit intents. You can also apply this approach to single activity application with navigation component with a little modification.



                  Here is navigation object for module B



                  object ModuleBNavigator {

                  internal lateinit var navigationImpl: ModuleBContract

                  fun setNavigationImpl(navigationImpl: ModuleBContract) {
                  this.navigationImpl = navigationImpl
                  }

                  interface ModuleBContract {
                  fun navigateModuleA(self: Activity, bundle: Bundle?)
                  }
                  }


                  And here is module B Activity



                  class ModuleBActivity : Activity() {

                  companion object {
                  private const val BUNDLE = "BUNDLE"
                  fun newIntent(context: Context, bundle: Bundle?) = Intent(context, ModuleBActivity::class.java).apply {
                  putExtra(BUNDLE, bundle)
                  }
                  }
                  }


                  And here is app module class to inject navigation impl to module A navigation object



                  class ApplicationModuleApp : Application() {

                  // Can also inject with a DI library
                  override fun onCreate() {
                  super.onCreate()
                  ModuleBNavigator.setNavigationImpl(object : ModuleBNavigator.ModuleBContract {
                  override fun navigateModuleA(self: Activity, bundle: Bundle?) {
                  self.startActivity(ModuleBActivity.newIntent(self, bundle))
                  }
                  })
                  }
                  }


                  And finally you can navigate from module A -> module B with provided implementation



                  class ModuleAActivity : Activity() {

                  override fun onCreate(savedInstanceState: Bundle?) {
                  super.onCreate(savedInstanceState)
                  // ... Some code
                  ModuleBNavigator.navigationImpl.navigateModuleA(this, Bundle())
                  // .. Some code
                  }
                  }


                  This approact avoids circler dependency and you don't have to use implicit intents anymore.
                  Hope this helps.






                  share|improve this answer













                  Here is my solution for stiuation. This enables the use of explicit intents. You can also apply this approach to single activity application with navigation component with a little modification.



                  Here is navigation object for module B



                  object ModuleBNavigator {

                  internal lateinit var navigationImpl: ModuleBContract

                  fun setNavigationImpl(navigationImpl: ModuleBContract) {
                  this.navigationImpl = navigationImpl
                  }

                  interface ModuleBContract {
                  fun navigateModuleA(self: Activity, bundle: Bundle?)
                  }
                  }


                  And here is module B Activity



                  class ModuleBActivity : Activity() {

                  companion object {
                  private const val BUNDLE = "BUNDLE"
                  fun newIntent(context: Context, bundle: Bundle?) = Intent(context, ModuleBActivity::class.java).apply {
                  putExtra(BUNDLE, bundle)
                  }
                  }
                  }


                  And here is app module class to inject navigation impl to module A navigation object



                  class ApplicationModuleApp : Application() {

                  // Can also inject with a DI library
                  override fun onCreate() {
                  super.onCreate()
                  ModuleBNavigator.setNavigationImpl(object : ModuleBNavigator.ModuleBContract {
                  override fun navigateModuleA(self: Activity, bundle: Bundle?) {
                  self.startActivity(ModuleBActivity.newIntent(self, bundle))
                  }
                  })
                  }
                  }


                  And finally you can navigate from module A -> module B with provided implementation



                  class ModuleAActivity : Activity() {

                  override fun onCreate(savedInstanceState: Bundle?) {
                  super.onCreate(savedInstanceState)
                  // ... Some code
                  ModuleBNavigator.navigationImpl.navigateModuleA(this, Bundle())
                  // .. Some code
                  }
                  }


                  This approact avoids circler dependency and you don't have to use implicit intents anymore.
                  Hope this helps.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 8 at 6:29









                  malik_cesurmalik_cesur

                  1235




                  1235

























                      1














                      For a different approach -actually similar which I mentioned in my question- which implementation belongs to sanogueralorenzo



                      Create a loader which laods the module classes



                      const val PACKAGE_NAME = "com.example.android"

                      private val classMap = mutableMapOf<String, Class<*>>()

                      private inline fun <reified T : Any> Any.castOrReturnNull() = this as? T

                      internal fun <T> String.loadClassOrReturnNull(): Class<out T>? =
                      classMap.getOrPut(this) {
                      try {
                      Class.forName(this)
                      } catch (e: ClassNotFoundException) {
                      return null
                      }
                      }.castOrReturnNull()


                      Create a String extension function for loading Intents dynamically.



                      private fun intentTo(className: String): Intent =
                      Intent(Intent.ACTION_VIEW).setClassName(BuildConfig.PACKAGE_NAME, className)

                      internal fun String.loadIntentOrReturnNull(): Intent? =
                      try {
                      Class.forName(this).run { intentTo(this@loadIntentOrReturnNull) }
                      } catch (e: ClassNotFoundException) {
                      null
                      }


                      Create another String extension function for loading Fragments dynamically



                      internal fun String.loadFragmentOrReturnNull(): Fragment? =
                      try {
                      this.loadClassOrReturnNull<Fragment>()?.newInstance()
                      } catch (e: ClassNotFoundException) {
                      null
                      }


                      Create an Feature interface for your feature implementations



                      interface Feature<T> {
                      val dynamicStart: T?
                      }


                      I assume that you have a Messages feature. Implement your dynamic feature interface



                      object Messages : Feature<Fragment> {

                      private const val MESSAGES = "$PACKAGE_NAME.messages.presentation.MessagesFragment"

                      override val dynamicStart: Fragment?
                      get() = MESSAGES.loadFragmentOrReturnNull()

                      }


                      And finally use it in another module without dependency



                       Messages.dynamicStart?.let {
                      if (savedInstanceState == null) {
                      supportFragmentManager.beginTransaction()
                      .replace(R.id.fl_main, it)
                      .commit()
                      }
                      }





                      share|improve this answer




























                        1














                        For a different approach -actually similar which I mentioned in my question- which implementation belongs to sanogueralorenzo



                        Create a loader which laods the module classes



                        const val PACKAGE_NAME = "com.example.android"

                        private val classMap = mutableMapOf<String, Class<*>>()

                        private inline fun <reified T : Any> Any.castOrReturnNull() = this as? T

                        internal fun <T> String.loadClassOrReturnNull(): Class<out T>? =
                        classMap.getOrPut(this) {
                        try {
                        Class.forName(this)
                        } catch (e: ClassNotFoundException) {
                        return null
                        }
                        }.castOrReturnNull()


                        Create a String extension function for loading Intents dynamically.



                        private fun intentTo(className: String): Intent =
                        Intent(Intent.ACTION_VIEW).setClassName(BuildConfig.PACKAGE_NAME, className)

                        internal fun String.loadIntentOrReturnNull(): Intent? =
                        try {
                        Class.forName(this).run { intentTo(this@loadIntentOrReturnNull) }
                        } catch (e: ClassNotFoundException) {
                        null
                        }


                        Create another String extension function for loading Fragments dynamically



                        internal fun String.loadFragmentOrReturnNull(): Fragment? =
                        try {
                        this.loadClassOrReturnNull<Fragment>()?.newInstance()
                        } catch (e: ClassNotFoundException) {
                        null
                        }


                        Create an Feature interface for your feature implementations



                        interface Feature<T> {
                        val dynamicStart: T?
                        }


                        I assume that you have a Messages feature. Implement your dynamic feature interface



                        object Messages : Feature<Fragment> {

                        private const val MESSAGES = "$PACKAGE_NAME.messages.presentation.MessagesFragment"

                        override val dynamicStart: Fragment?
                        get() = MESSAGES.loadFragmentOrReturnNull()

                        }


                        And finally use it in another module without dependency



                         Messages.dynamicStart?.let {
                        if (savedInstanceState == null) {
                        supportFragmentManager.beginTransaction()
                        .replace(R.id.fl_main, it)
                        .commit()
                        }
                        }





                        share|improve this answer


























                          1












                          1








                          1







                          For a different approach -actually similar which I mentioned in my question- which implementation belongs to sanogueralorenzo



                          Create a loader which laods the module classes



                          const val PACKAGE_NAME = "com.example.android"

                          private val classMap = mutableMapOf<String, Class<*>>()

                          private inline fun <reified T : Any> Any.castOrReturnNull() = this as? T

                          internal fun <T> String.loadClassOrReturnNull(): Class<out T>? =
                          classMap.getOrPut(this) {
                          try {
                          Class.forName(this)
                          } catch (e: ClassNotFoundException) {
                          return null
                          }
                          }.castOrReturnNull()


                          Create a String extension function for loading Intents dynamically.



                          private fun intentTo(className: String): Intent =
                          Intent(Intent.ACTION_VIEW).setClassName(BuildConfig.PACKAGE_NAME, className)

                          internal fun String.loadIntentOrReturnNull(): Intent? =
                          try {
                          Class.forName(this).run { intentTo(this@loadIntentOrReturnNull) }
                          } catch (e: ClassNotFoundException) {
                          null
                          }


                          Create another String extension function for loading Fragments dynamically



                          internal fun String.loadFragmentOrReturnNull(): Fragment? =
                          try {
                          this.loadClassOrReturnNull<Fragment>()?.newInstance()
                          } catch (e: ClassNotFoundException) {
                          null
                          }


                          Create an Feature interface for your feature implementations



                          interface Feature<T> {
                          val dynamicStart: T?
                          }


                          I assume that you have a Messages feature. Implement your dynamic feature interface



                          object Messages : Feature<Fragment> {

                          private const val MESSAGES = "$PACKAGE_NAME.messages.presentation.MessagesFragment"

                          override val dynamicStart: Fragment?
                          get() = MESSAGES.loadFragmentOrReturnNull()

                          }


                          And finally use it in another module without dependency



                           Messages.dynamicStart?.let {
                          if (savedInstanceState == null) {
                          supportFragmentManager.beginTransaction()
                          .replace(R.id.fl_main, it)
                          .commit()
                          }
                          }





                          share|improve this answer













                          For a different approach -actually similar which I mentioned in my question- which implementation belongs to sanogueralorenzo



                          Create a loader which laods the module classes



                          const val PACKAGE_NAME = "com.example.android"

                          private val classMap = mutableMapOf<String, Class<*>>()

                          private inline fun <reified T : Any> Any.castOrReturnNull() = this as? T

                          internal fun <T> String.loadClassOrReturnNull(): Class<out T>? =
                          classMap.getOrPut(this) {
                          try {
                          Class.forName(this)
                          } catch (e: ClassNotFoundException) {
                          return null
                          }
                          }.castOrReturnNull()


                          Create a String extension function for loading Intents dynamically.



                          private fun intentTo(className: String): Intent =
                          Intent(Intent.ACTION_VIEW).setClassName(BuildConfig.PACKAGE_NAME, className)

                          internal fun String.loadIntentOrReturnNull(): Intent? =
                          try {
                          Class.forName(this).run { intentTo(this@loadIntentOrReturnNull) }
                          } catch (e: ClassNotFoundException) {
                          null
                          }


                          Create another String extension function for loading Fragments dynamically



                          internal fun String.loadFragmentOrReturnNull(): Fragment? =
                          try {
                          this.loadClassOrReturnNull<Fragment>()?.newInstance()
                          } catch (e: ClassNotFoundException) {
                          null
                          }


                          Create an Feature interface for your feature implementations



                          interface Feature<T> {
                          val dynamicStart: T?
                          }


                          I assume that you have a Messages feature. Implement your dynamic feature interface



                          object Messages : Feature<Fragment> {

                          private const val MESSAGES = "$PACKAGE_NAME.messages.presentation.MessagesFragment"

                          override val dynamicStart: Fragment?
                          get() = MESSAGES.loadFragmentOrReturnNull()

                          }


                          And finally use it in another module without dependency



                           Messages.dynamicStart?.let {
                          if (savedInstanceState == null) {
                          supportFragmentManager.beginTransaction()
                          .replace(R.id.fl_main, it)
                          .commit()
                          }
                          }






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Apr 5 at 7:45









                          savepopulationsavepopulation

                          8,02543753




                          8,02543753






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54037244%2fdesigning-modular-apps-circular-dependency-problem-in-navigation%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Monofisismo

                              Angular Downloading a file using contenturl with Basic Authentication

                              Olmecas