发现接口依赖关系

4
我接手了一个非常大的 (>2M SLOC) C#软件项目的维护工作,但很少有文档。现在我想改变一个具有公共接口(约400个)的模块,但我不知道解决方案中的其他模块(总共约50个)是否正在使用此公共接口。
那么,在这种情况下如何创建接口依赖关系使用树呢?源代码太多,无法简单地浏览 Project Explorer 并阅读源代码。您用过哪些工具或方法来创建这种依赖分析树?
我不想购买任何工具。Visual Studio 工具,如 Class View,在处理这样大小的项目时似乎表现不佳。我曾经考虑编写自己的 sed/awk/perl 脚本,简单遍历源代码并使用模式匹配构建自己的依赖关系/接口使用数据库,但如果有简单的方法,我不想走一条艰难的路。
谢谢!
6个回答

3

我建议你购买类似于NDepend的工具。

如果有其他免费的工具能提供类似的价值,我会推荐它。然而,我真的相信NDepend是最好的选择。对于那么大的代码库来说,一款价值400美元的工具很快就能回本了。


如果您想要的话,可以使用免费试用版本。 - ShuggyCoUk

2
我强烈建议您寻找现有的工具来完成这项任务。您永远无法通过手动解决整个问题,而使用工具节省的时间肯定可以用于支付工具本身的成本。
我的一个同事曾经遇到了这个问题 - 他的经理不愿意为分析器付款,结果他们花了5天开发时间优化程序的错误部分。使用分析器,他在半天内找到并修复了问题。

1

我知道你说你不想购买工具,但CodeRush完全功能可用,而且免费使用一个月(之后仅需$250,你还将获得非常棒的Refactor Pro!)。它可以用一个非常巧妙的查找所有引用窗口代替Shift+F12。


1

直接依赖的简单解决方案,右键单击接口并选择“查找所有引用”。您也可以按方法基础执行此操作。

要找出由于更改而导致多少代码中断,您可以将[Obsolete(true,“Testing The change”)]添加到计划更改的接口上的方法中,并触发重建。这将导致某些部分无法构建。 跳过这些部分,并使用[Obsolete(false,“Limited Change”)]标记它们,如果您认为这是该类的小变化,并且您可以在不影响该类的消费者的情况下修复它,则可以。如果您认为这将对类的消费者造成重大问题,则可以将其标记为[Obsolete(true,“Cascade”)]并处理后果。

最终,您的解决方案将完全构建,或者您将有太多错误,以至于显然更改是如此具有侵入性,以至于真正掌握其影响的唯一方法是开始尝试。

这种方法的好处在于,您可以进行级联而无需实际处理如何处理它,只需要知道您需要并大致评估它是否会触发连带更改。一旦您确定已经映射出所做的更改,您就拥有了一个准备好的警告列表,在您修改接口本身(以及构建方式真正失败)时可以使用IDE进行更改。

这取决于不将警告视为错误,您可能需要暂时放松构建设置。

在全新的源代码更新中完成所有这些操作,这样如果您想再试一次,就可以将某些部分回滚。


好的建议。然而,这更像是一种“蛮力”方法。我希望能找到一种在编译/构建之前查看所有依赖项的方法。 - Todd
+1 从来不知道过时标签有实际用途。以为它只是装饰性的。 - George Mauer

1

小提示:当您要构建自己的工具版本时,您也可以使用反射来编译程序集。

.NET为您提供了加载程序集并查询System.Reflection命名空间中的所有接口、类型、方法和属性所需的一切。这样,您就不必担心使用sed/awk/perl自己解析源代码(这并不容易,因为您需要解析命名空间和继承)。

(注意:使用反射无法直接获取动态加载程序集(例如通过Assembly.Load加载的程序集)的程序集依赖项。如果在您的项目中使用了这些内容,则需要实现特殊处理)


跟进问题:有没有一种方法可以检查已编译的DLL并查看它调用了哪些其他DLL?如果我们能够获取方法名称和入口点,那就更好了。谢谢!-Todd - Todd

0

我不知道你的项目是如何设置的,但我们这里每个模块都有一个版本号。当我们需要对一个模块进行更改时,我们会创建一个新版本。想要使用新接口的客户端代码链接到更新的模块并删除对旧项目的引用。通过不同的版本,更改API时就不会出现意外的副作用;客户端代码必须明确地执行某些操作。

此外,我们还有一个实用程序(以某种方式)遍历所有项目,并报告是否有任何项目正在使用不是最新版本的模块。即使使用Microsoft VSS,检查哪些项目引用了过时的模块也很容易。


2个问题:1)当您谈论模块版本号时,您是指DLL /程序集版本吗?这听起来像是在发布新版本后尝试进行构建,然后逐个修复构建错误?2)您第二段中提到的实用程序是自制工具吗?谢谢! - Todd
我们是一个Java开发团队,因此版本号相当随意。版本号在模块的文件名中,例如LoggingModule_1.01.01.jar。当有新版本的模块时,不会出现构建错误,因为项目必须显式导入新版本。是的,这是自主开发的。 - Tim Frey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接