Сортировка классов в порядке зависимости (NDepend)

Я новичок в NDepend и просто промокну ноги. Я могу создать график зависимостей классов, используя следующий простой запрос:

from t in Application.Types
// remove compiler generated classes
where !t.FullName.Contains(">")
// sort by dependency count
orderby t.TypesUsed.Count()
select new { t, t.TypesUsed }

Я пытаюсь построить упорядоченный список классов таким образом, чтобы первые элементы в списке не имели зависимостей, отличных от системных типов. По мере продвижения по списку каждый тип должен иметь только зависимости, которые появляются перед ним в списке. Я понимаю, что в случаях с циклическими зависимостями это невозможно, но я хотел бы, по крайней мере, привести их в более правильный порядок, чем просто упорядочивать по количеству зависимостей.


person mhand    schedule 18.06.2018    source источник


Ответы (1)


Это сложно, но возможно. Этот запрос кода CQLinq использует магию метода NDepend.API FillIterative().

// The call FillIterative() will fill hashSet with types already processed
let hashSet = new HashSet<IType>()

let fillHashSetWithTypesFunc = new Func<IEnumerable<IType>, bool>(types => types.All(t => hashSet.Add(t)))

let metric = ThirdParty.Types.FillIterative(
   types => 
      // Use a ternary operator to invoke fillHashSetWithTypesFunc() that always return true,
      fillHashSetWithTypesFunc(types) ?
         // Select t when hashSet contains all t.TypesUsed
         Application.Types.Where(t => t.TypesUsed.Intersect(hashSet).Count() == t.TypesUsed.Count()) :
         // new IType[0] is never invoqued coz fillHashSetWithTypesFunc() always returns true
         new IType[0])

from val in metric 
where val.Value > 0  // Don't show third-party types
orderby val.Value ascending
select new { val.CodeElement, 
   (val.CodeElement as IType).Level, 
   val.Value, 
   (val.CodeElement as IType).TypesUsed }

Типы, участвующие в цикле, не совпадают.

Результат присваивает значение каждому совпавшему типу:

  • (1) являются типами, использующими только сторонние типы
  • (2) являются типами с использованием сторонних и типов в (1)
  • (3) ...

Интересно, что метрика IType.Level обеспечивает именно эту меру и отвечает на ваш вопрос. Но гораздо интереснее переписать его с помощью кода запроса. То же самое можно сделать с пространствами имен (которые также имеют метрику уровня), сборками и методами.

Метрика уровня применяется к типу

person Patrick from NDepend team    schedule 19.06.2018