我在 NDepend 上有点挣扎。这有点难以解释。我的代码库中有一个方法(让我们调用该方法'TheMethod'),它不能被某种其他方法调用(让我们称这种方法为'TheKind'),除非它们用某些属性('TheAttr' ),直接或间接;如果是间接的,任何用“TheAttr”装饰的跃点都应该不会违反间接使用。
我将使用“->”箭头表示“使用”的一些场景,以及具有上述属性的方法,带有“[TheAttr]”的TheAttr,如果应该违反规则,则使用“FAIL”/“SUCCESS”如果不应违反该规则。
所以...
我可以编写一个 CQLinq 查询,直接或间接使用“TheMethod”触发“TheKind”的所有方法。我还可以从结果中排除具有“TheAttr”的方法。
somemethod -> TheMethod FAIL
somemethod[TheAttr] -> TheMethod SUCCESS
将间接用法纳入规则也很容易:
somemethod -> method1 -> method2 -> TheMethod FAIL
somemethod[TheAttr] -> method1 -> method2 -> TheMethod SUCCESS
现在,我想要的是:
somemethod -> method1[TheAttr] -> method2 -> TheMethod SUCCESS
和
somemethod -> method1 -> method2[TheAttr] -> TheMethod SUCCESS
因此,换句话说,任何具有装饰的中间调用者都应该导致“TheMethod”的有效用法/“通过”有效用法的调用也应该是有效的。
可以用 NDepend 检查吗?我尝试了 FillIterative 但到目前为止没有运气。
谢谢,蒂姆
PS.:这是我目前的尝试:
warnif count > 0
let mcalling = Methods.WithFullName("My.Namespace.MyType.get_SomeProperty()").SingleOrDefault().MethodsCallingMe.ToList()
let domain = mcalling.FillIterative(callers => // Unique loop, just to let a chance to build the hashset.
from o in (new object()).ToEnumerable()
let hashset = callers.ToHashSet() // Use a hashet to make Intersect calls much faster!
from m in Methods.UsingAny(callers).Except(callers)
where !m.HasAttribute("My.Namespace.NDependIgnore.MayUsePropAlthoughAsync".AllowNoMatch())
select m
)
let indirectcallers = domain.DefinitionDomain.Where(m1 => m1.IsAsync).ToArray() // Avoid double enumeration
from m in indirectcallers
let depth = m.DepthOfIsUsing("My.Namespace.MyType.get_SomeProperty()")
where depth >= 0
select new
{
Method=m,
Depth=depth,
Level=domain[m]
}