예 NDepend가 효율적으로 날 당신이 생각하는 것보다 쉬울 수 있기 때문에 방법을 설명하자 순환 참조 찾을 수 있습니다 (면책 조항 : 나는 NDepend에 대한 개발자의 일 오전). 지금까지 당신은 찾을 수 네임 스페이스 의존성주기 아웃 - 오브 - 박스 내가 아래에 설명하고, 네임 스페이스에 유형, 또는 방법 (A)의 사이뿐만 아니라 사이클을 쉽게 찾을 수하지만, 유형.
네임 스페이스 종속성주기를 나열하는 default C# LINQ code rule이 있습니다. 이러한 순환은 종속성 그래프 또는 종속성 매트릭스로 내보낼 수 있습니다. 다음은 Roslyn 코드 기반 CTP (2012 년 6 월)에서 실행 된 규칙의 스크린 샷입니다 (실행하는 데 16 밀리 초가 걸렸음을 알 수 있습니다). 그것은 11 별개의 사이클을 발견하고 스크린 샷과 같이, 각주기를 드릴 다운 및 그래프에주기를 내보낼 수 있습니다
다음
는 7 네임 스페이스 사이클의 종속성 그래프이다. 고전적인 O 링 사이클보다 더 복잡해 보입니다. 여기서 핵심은 이러한 네임 스페이스 중 하나에서 다른 모든 네임 스페이스에 도달 할 수 있다는 것입니다. 이것은주기 (얽힘)의 일반화 된 개념입니다.
네임 스페이스 종속성주기를 나열하는 default C# LINQ code rule의 코드는 먼저 눈에 발굴 보일 수 있습니다. 그러나 C# 개발자는 몇 분 안에이를 이해해야하며 모든 종류의 종속성주기를 쉽게 찾을 수 있습니다.
예를 들어, 그것은 방법 모든 공간 단어를 교체하는 것만큼이나 간단 동일한 타입의주기 방법 (대신 동일한 어셈블리 사이클을의 스페이스)을 발견하고, 조립체 단어별로 유형.
// <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 }
...이 규칙의 결과는 다음과 같습니다 (여전히 의존성 그래프 또는 매트릭스로 메소드주기를 내보낼 가능성이 있음).메서드 및 유형 수가 네임 스페이스 및 어셈블리 수보다 훨씬 많기 때문에이 쿼리는 Roslyn과 같은 대규모 코드 기반에서 실행될 때 10 초가 걸렸으며 (네임 스페이스주기의 경우 16ms 대신)이 조정을 조정해야 할 수도 있습니다 CQLinq 쿼리 실행 시간 제한 (기본값 당 2 초).
완료하기 위해, 내가 무엇을 발견하면 해당주기가 몇 양방향 참조에 의해 유발 대부분의 시간을하는 것입니다 (즉 A, B가 사용하고 B를 사용하고 있습니다). 따라서 양방향 참조를 제거하는 것이 순환을 중단시키는 첫 번째 방법입니다. 그렇기 때문에 우리는 기본 CQLinq 규칙 Avoid namespaces mutually dependent을 제공 했으므로 형식이나 메서드주기에 계속 적용 할 수 있습니다.
순환 참조를 빠르게 찾을 수있는 관련 유틸리티 : http://stackoverflow.com/a/43374622/64334 –