From the example you provided in the update, I'd express your need in terms of static (instead of hard) and dynamic (instead of soft) dependencies.
I wouldn't consider as a design problem if ClientImpl
uses statically LocationImpl
and LocationImpl
uses dynamically ClientImpl
(through a ClientInterface
). ClientImpl
could even inject itself in LocationImpl
through a LocationImpl
method that would take a ClientInterface
as argument. This constitutes a pretty widely adopted object-oriented pattern (call it Injection of Control, or Dependency Injection the philosophy behind is the same, see what Martin Fowler wrote about it almost a decade ago).
Btw, all this implies that ClientImpl
has a higher level than LocationImpl
that itslef has a higher level than ClientInterface
.
When design documentation refers to circular dependencies as a major design problem, it typically refers to static/hard dependencies.
This question has arisen from the fact that C# doesn't allow projects to have circular dependencies between projects and I use projects to isolate components in my system.
Indeed, because chances are very high that if two assemblies reference each others, a static/hard dependencies would be created. MS has always considered assemblies as the .NET way to implement the notion of component and thus, VS prevents circular dependencies between components.
Interestingly enough, the .NET Framework design comes with several circular assemblies dependencies!