How do you solve circular reference problems like Class A has class B as one of its properties, while Class B has Class A as one of its properties?
How to do ar开发者_运维百科chitect for those kind of problems?
If you take an example of NHibernate, there will be a parent-child relationship between objects.
How is it able to handle those parent child scenarios?
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.
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:
- Move the common referenced code to a utility project in your solution and have the other projects reference the Utility project
- Use an interface as explained by "Ed Bayiates" in his answer.
- 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
interfaces are a good idea however if your looking for a quicker solution than redoing the architecture of so many things try building one dll class library that holds all your data structures your main project holds your UI that needs that data and then any other dlls you want to add can access that data structures dll as well so they have all the info they need to run but still can be separate- this is called the tri force design pattern -
Circular reference occurs when two or more interdependent resources cause lock condition. This makes the resource unusable.
To handle the problem of circular references in C#, you should use garbage collection. It detects and collects circular references. The garbage collector begins with local and static and it marks each object that can be reached through their children.
Through this, you can handle the issues with circular references.
Let’s say the following classes is in circular reference. Here both of them depends on each other −
public class A
{
B Two;
}
public class B
{
A one;
}
To solve the issue, create an interface −
public interface myInterface {
}
public class A {
myInterface Two;
}
public class B: myInterface {
A one;
}
精彩评论