按依赖顺序 (NDepend) 对 类 进行排序
Sort classes in dependency order (NDepend)
我是 NDepend 的新手,刚开始接触。我可以使用以下简单查询创建 class 依赖关系图:
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 }
我正在尝试构建一个 classes 的有序列表,以便列表中的第一个项目没有系统类型以外的依赖项。当我们在列表中前进时,每种类型应该只具有列表中出现在它之前的依赖项。我意识到在具有循环依赖性的情况下这是不可能的,但我希望至少让它们的顺序比简单地按依赖计数排序更正确。
这是一个虽然棘手但可行的方法。此 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 提供了准确的衡量标准并回答了您的问题。但是用代码查询重新编写它更有趣。命名空间(也有 Level 指标)、程序集和方法也可以这样做。
我是 NDepend 的新手,刚开始接触。我可以使用以下简单查询创建 class 依赖关系图:
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 }
我正在尝试构建一个 classes 的有序列表,以便列表中的第一个项目没有系统类型以外的依赖项。当我们在列表中前进时,每种类型应该只具有列表中出现在它之前的依赖项。我意识到在具有循环依赖性的情况下这是不可能的,但我希望至少让它们的顺序比简单地按依赖计数排序更正确。
这是一个虽然棘手但可行的方法。此 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 提供了准确的衡量标准并回答了您的问题。但是用代码查询重新编写它更有趣。命名空间(也有 Level 指标)、程序集和方法也可以这样做。