Circular reference — architecture question

What you have are not so much circular references as two examples of

a parent-child relationship which is navigable from both ends.

Yes it is normal and acceptable and no it isn't a code smell. Yes, some serialization tools require you to hint. e.g. Newtonsoft.Json would want the ReferenceLoopHandling.Ignore setting.

Navigability as a concept is not always talked about in OO design, which is unfortunate because it's just the concept you want here. (It is an explicit term in UML).

You often don't need navigability from both ends. Parent-child relationships are often coded from parent to child only. This is really common. For instance, an invoiceline class rarely needs an explicit field for its parent invoice because most applications only ever look at the line after retrieving the parent invoice.

So the design decision is not,

"Does a revison make sense without a drawing?"

But

"Will I ever need to find a drawing given only a revision?"

My guess is that your revisions are like invoice lines, and don't need to navigate to their parent. The answer for the drawings <——> project relation is not obvious to me. (It is an analysis question about your domain, not a question about coding style).

There is a striking difference here between OO code and, for instance, SQL. In a SQL database, it must be the revision table that holds the reference to its parent drawing id. In OO code, the parent class nearly-always holds a reference to the children. The children often don't need a reference to their parent because the only way you access the children is by already having the parent.


Circular references are quite normal in C# programs and data models in general, so don't worry about them. They do have to be specially handled during serialization though.