查找仅通过NDepend在特殊类中使用的代码

时间:2012-11-02 14:43:31

标签: c# dependency-injection ndepend static-code-analysis

我正在尝试使用NDepend删除代码库中的死代码。由于我们使用依赖注入,我想找到仅在从注册表库派生的类中使用的接口(和实现):

public class PresenterRegistry : Registry
{
    public PresenterRegistry()
    {
        For<IExamplePresenter>().Use<ExamplePresenter>();
    }
}

有没有办法做到这一点?

谢谢!

2 个答案:

答案 0 :(得分:1)

我不确定你要求的是什么。

我想找到仅在从注册表库派生的类中使用的接口(和实现):以下查询匹配从{{1}派生的任何类型使用的应用程序接口和类}:

Microsoft.Win32.Registry

..并且在下一个查询中,您还可以获得接口的派生类型和实现,在上一个查询中匹配:

let registryDerived = Application.Types.Where(t => t.DeriveFrom("Microsoft.Win32.Registry"))
from t in Application.Types.UsedByAny(registryDerived)
select t

...或列出所有内容:

let registryDerived = Application.Types.Where(t => t.DeriveFrom("Microsoft.Win32.Registry"))
from t in Application.Types.UsedByAny(registryDerived)
let tDerived = t.DerivedTypes
let tImpl = t.TypesThatImplementMe
select new { t, tDerived, tImpl }

顺便说一句,let registryDerived = Application.Types.Where(t => t.DeriveFrom("Microsoft.Win32.Registry")) let tUsed = Application.Types.UsedByAny(registryDerived) let tDerived = tUsed.SelectMany(t => t.DerivedTypes) let tImpl = tUsed.SelectMany(t => t.TypesThatImplementMe) from t in tUsed.Union(tDerived).Union(tImpl) select t 是封闭的,所以这不是你所说的课程。但是你可以用自己的类名替换它,前缀为namespace。

答案 1 :(得分:1)

尝试了一下后,我创建了一个以我需要的方式工作的查询:

// <Name>Interfaces registered but potentially not used</Name>
warnif count > 0 
from t in JustMyCode.Types
from i in JustMyCode.Types
where t.DeriveFrom("StructureMap.Configuration.DSL.Registry")
   && i.IsInterface
   && t.IsUsing(i)
   && i.NbTypesUsingMe < 3 // one using for implementation, one in registry
select i

没有我预期的那么多代码:-)这个查询不包括任何可能性,但它是一个好的开始。

尽管如此:帕特里克,谢谢你的帮助!


欢迎Rico :)顺便说一句,这个代码规则可以通过这种方式重写,以 O(N)而不是 O(N ^ 2)运行( N是 JustMyCode.Types 的数量。这种优化是通过神奇的UsedByAny()方法实现的。此规则还提供了更详细的结果。

warnif count > 0 
let registryDerived = JustMyCode.Types.Where(t => t.DeriveFrom("StructureMap.Configuration.DSL.Registry"))
from i in JustMyCode.Types.UsedByAny(registryDerived)
where i.IsInterface &&
      i.NbTypesUsingMe < 3 // one using for implementation, one in registry
select new { i, 
             registryDerivedUser = i.TypesUsingMe.Intersect(registryDerived),
             i.TypesUsingMe }