Yes NDepend can find circular links. Effectively let me explain how this could be easier than you might think (Disclaimer: I am one of the developers of NDepend). While you can find the namespace dependency loop outside the box, but as I explain below, it is easy to find loops between types in the namespace or type methods as well.
There is a default C # LINQ rule that lists namespace dependency loops. This loop can then be exported to a dependency graph or dependency matrix. Here's a screenshot of a rule based on the Roslyn CTP code, June 2012 (only 16 milliseconds were spent notice). He discovered 11 different cycles, and as shown in the screenshot, you can expand each cycle and export the cycle to the chart:

Here is a dependency graph of a loop of 7 namespaces. Note that this looks more complicated than just the classic O-ring loop. The key point here is that from any of these namespaces, you can span everything else. This is a generalized concept of a cycle (confusion).

The default C # LINQ rule code, which lists dependency cycles between namespaces, at first glance looks scary. But a C # developer should figure this out in a few minutes and then easily adapt it to find some kind of dependency cycle.
For example, to find methods of the same cycle types (instead of the namespace of the same assembly cycles ), it is almost as simple as replacing all the words in the namespace with the method and assembly by type.
// <Name>Avoid methods of a type to be in cycles</Name> warnif count > 0 from t in Application.Types .Where(t => t.ContainsMethodDependencyCycle != null && t.ContainsMethodDependencyCycle.Value) // Optimization: restreint methods set // A method involved in a cycle necessarily have a null Level. let methodsSuspect = t.Methods.Where(m => m.Level == null) // hashset is used to avoid iterating again on methods already caught in a cycle. let hashset = new HashSet<IMethod>() from suspect in methodsSuspect // By commenting this line, the query matches all methods involved in a cycle. where !hashset.Contains(suspect) // Define 2 code metrics // - Methods depth of is using indirectly the suspect method. // - Methods depth of is used by the suspect method indirectly. // Note: for direct usage the depth is equal to 1. let methodsUserDepth = methodsSuspect.DepthOfIsUsing(suspect) let methodsUsedDepth = methodsSuspect.DepthOfIsUsedBy(suspect) // Select methods that are both using and used by methodSuspect let usersAndUsed = from n in methodsSuspect where methodsUserDepth[n] > 0 && methodsUsedDepth[n] > 0 select n where usersAndUsed.Count() > 0 // Here we've found method(s) both using and used by the suspect method. // A cycle involving the suspect method is found! let cycle = usersAndUsed.Append(suspect) // Fill hashset with methods in the cycle. // .ToArray() is needed to force the iterating process. let unused1 = (from n in cycle let unused2 = hashset.Add(n) select n).ToArray() select new { suspect, cycle }
... and this is what the result of this rule looks like (itβs still possible to export the method loop to a dependency graph or matrix). Please note: since the number of methods and types is much larger than the number of namespaces and assemblies, this request took 10 seconds to work on a large code base such as Roslyn (instead of 16 ms for the namespace loop), so you may need to configure the execution timeout CQLinq query (default is 2 seconds).

To be complete, I noticed that the loop in most cases is triggered by several bidirectional links (for example, A uses B, B uses A). Therefore, removing bidirectional links is the first thing to do to break the loop. That's why we provided the default CQLinq rule. Avoid interdependent namespaces that can still be adapted to types or methods.