views:

578

answers:

6

I'm trying to use an IOC container to create the initial object graph within my application.

I have a MainForm. This form depends on a MenuStrip, which depends on multiple MenuStripItems. Some MenuStripItems depend on the MainForm.

At the moment I setup all dependencies for constructor injection. Obviously, resolving the MainForm now results in a stack overflow, since the MenuStripItem dependencies of the MainForm try to resolve the Mainform, etc etc...

What's the best way to resolve this circular dependency?

+3  A: 

Circular dependencies are a sign of bad design, no matter if you are using IoC or not. I suggest that you do a redesign to avoid it. Adding a helper object may be a solution.

For example, make the MenuStripItems depend only on one part of the MainForm that is necessary for them and not on the whole.

kgiannakakis
+3  A: 

Make a controller class which provides the data and logic which the MainForm and MenuStripItem both needs to avoid the circular reference.

Gerrie Schenck
+1  A: 

You can use a setter for injecting some of the dependencies after construction.

starblue
A: 

I don't see how creating a helper class or controller solves the circular dependency problem.

I'll give some more details. The MenuStripItems depend on MainForm because they can set the Content of the MainForm. Following the above suggestions, let's say I create a seperate interface for the MainForm Content, IFormContent. MenuStripItem can then depend on IFormContent. But an implementation of IFormContent will then again depend on MainForm, resulting in a circular dependency.

Perhaps I should resort to setter injection somewhere instead of constructor injection?

You have a controller class with one property: Content. MenuStripItem sets the Content property on the controller, and MainForm reads it. So these two classes reference the controller, but the controller knows nothing about the two GUI classes. So no circular reference.
Gerrie Schenck
A: 

How are the MenuStrip and MenuStripItems created?

When I've used IOC, there is always a 1-to-1 relationship between a service and the dependencies which the IOC container provides for the service. If a service needs more than one of something, it would then have a 1-to-1 relationship with a single factory object that creates the multiple items. This factory method could be parameterized to allow the created items to refer back to their container.

Frank Schwieterman
A: 

I agree with kgiannakakis:

Circular dependencies are a sign of bad design, no matter if you are using IoC or not. I suggest that you do a redesign to avoid it. Adding a helper object may be a solution.

To find out which methods should be extracted into the helper class, this process may help:

Given you have a class A and a Class B which reference to each other and create a circular dependency. To find out which methods to extract into an external helper oject, list all of the methods in your class A used by class A, and all the methods in your class B used by class A. The shorter of the two lists is your hidden helper class C.

Inspired by Miško Hevery http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/

Andreas