5

If you search for how to resolve circular dependencies, the answer is almost always "use interfaces". I know how this technique can be used to make a circular dependency work, but I do not understand how that is solving a circular dependency.

Say I have 2 classes View and Presenter which reference each other. Now I apply the "solution" and create the interfaces IView and IPresenter. View does not reference Presenter anymore, but IPresenter; Presenter references IView instead of View.

  1. I set up View, which needs an IPresenter.
  2. To get an implementation of IPresenter I need to set up Presenter.
  3. To set up Presenter, I need an IView.
  4. To get an implementation of IView, I need to set up View.

The circle has gotten bigger, but it is still there. View and Presenter still depend on each other, just not directly. However, every answer I have seen is absolutely sure that the circular dependency is now resolved. What is my misunderstanding here?

Raphael Schmitz
  • 551
  • 5
  • 19

2 Answers2

4

These circular dependencies are not being solved.

The standard answer in these situations is to assign the dependency after construction. This solves the problem that these circular dependencies create, but not the circular dependencies themselves.

It's probably mostly a language issue where people just say "I solved the circular dependency between X and Y" instead of "I solved the issue we had because of the circular dependency between X and Y".

Raphael Schmitz
  • 551
  • 5
  • 19
  • I fully agree with this statement. Adding interfaces prevents the compiler from seeing the circular dependency, but it does not resolve it. – olenz Feb 14 '22 at 12:05
  • To resolve it, you have to restructure your code. There is no simple technical recipe for doing that. For reference, look here: https://blog.ttulka.com/too-many-interfaces ("Interfaces Solve Circular Dependencies") – olenz Feb 14 '22 at 12:11
2

Circular dependencies can be resolved using DI but only using "delayed" or "property" injection, not "constructor" injection. You would need to construct the objects first, then set properties on them to inject the dependencies. A DI container that supports property injection could abstract this detail away.

JoelFan
  • 37,465
  • 35
  • 132
  • 205
  • 1
    That is what I meant with " I know how this technique can be used to make a circular dependency work". The classes are still depending on each other then, though. – Raphael Schmitz May 18 '17 at 08:45