How to solve circular reference?

I would tell your friend he needs to rethink his design. Circular references like you describe are often a code smell of a design flaw.


Unlike C++ (for instance), C# does not need forward declarations to resolve circular references. Hence:

public class A
{
    public B B { get;set; }
}

public class B
{
    public A A { get;set; }
}

However, this is often an indicator of questionable design decisions.


In most every case the best solution is to change your design and avoid a circular dependency. For instance you may do one of the following:

  1. Move the common referenced code to a utility project in your solution and have the other projects reference the Utility project
  2. Use an interface as explained by "Ed Bayiates" in his answer.
  3. If its a small amount of simple/common code then rewrite it for one of the classes so you don't need to reference it in a circular dependency. (my least favorite)

However, if you are working in a solution with many projects and you don't have the ability to make one of the changes above because you don't own the code, its to difficult to implement, or not worth the time to fix, then You can use this method:

Right-click on the project references and select "Add Reference...". Then in the dialog window that appears switch to the "Browse" tab and the "Browse" button. From there you can go find the DLL and select it. This is a work around at best and can cause build problems especially if both DLLs are being updated frequently, and/or have many dependencies. I do not recommend this method but it works in a pinch.

Fissh


In most cases when I've had to have two things reference each other, I've created an interface to remove the circular reference. For example:

BEFORE

public class Foo
{
    Bar myBar;
}

public class Bar
{
    Foo myFoo;
}

Dependency graph:

Foo     Bar
 ^       ^
 |       |
Bar     Foo

Foo depends on Bar, but Bar also depends on Foo. If they are in separate assemblies, you will have problems building, particularly if you do a clean rebuild.

AFTER

public interface IBar
{
}

public class Foo
{
    IBar myBar;
}

public class Bar : IBar
{
    Foo myFoo;
}

Dependency graph:

Foo, IBar     IBar
    ^          ^
    |          |
   Bar        Foo

Both Foo and Bar depend on IBar. There is no circular dependency, and if IBar is placed in its own assembly, Foo and Bar being in separate assemblies will no longer be an issue.