4

我已经接管了一个非常大的(> 2M SLOC)软件项目的维护,所有这些都是用 C# 编写的。文档很少。我现在想要对具有公共接口(大约 400 个)的模块进行更改,但我不知道解决方案中的所有其他模块(总共大约 50 个)可能正在使用这个公共接口。

对于这种情况,您将如何创建接口依赖关系使用树?代码库太大,无法简单地浏览 Project Explorer 并阅读源代码。您使用了哪些工具或方法来创建这种类型的依赖关系分析树?

我不想购买任何工具。诸如 Class View 之类的 Visual Studio 工具似乎不能很好地处理这种规模的项目。我曾考虑编写自己的 sed/awk/perl-ish 脚本,该脚本简单地遍历源代码并使用模式匹配来构建我自己的依赖项/接口使用数据库,但如果有的话,我不想做一些艰难的事情一个简单的方法。

谢谢!

4

6 回答 6

3

您可能应该购买NDepend 之类的东西。

如果有另一个免费工具可以提供类似的价值,我会推荐它。但是,我真的相信 NDepend 是您最好的选择。有了这么大的代码库,400 美元的工具很快就能收回成本。

于 2009-01-28T20:30:24.147 回答
2

我认真地建议只找到一个现有的工具来做到这一点。您永远无法将整个事情手动整理好,使用工具节省的时间肯定会支付工具本身的成本。

一个同事遇到了这个问题——他的经理不会为分析器付费,所以他们花了 5 天的时间来优化程序的错误部分。使用分析器,他在半天之内发现并解决了问题。

于 2009-01-28T23:14:53.470 回答
1

我知道您说过您不想购买工具,但CodeRush功能齐全且可免费使用一个月(之后只需 250 美元,您就可以获得 refactor pro!这太棒了)。它用一个非常漂亮的查找所有引用窗口替换了 Shift+F12。

于 2009-01-28T20:29:58.950 回答
1

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

要了解更改会导致多少代码中断,您可以将 [Obsolete(true,"Testing The change")] 添加到您计划更改的接口上的方法中并触发重建。这将导致某些部分无法构建。跳到这些部分并用 [Obsolete(false, "Limited Change")] 标记它们,如果你觉得这是对该类的一个小改动,并且你可以修复它而不会对这个类的消费者产生任何影响,如果你认为改为这个会对类的消费者造成重大问题,您可以将其标记为 [Obsolete(true, "Cascade")] 并处理后果。

最终,您的解决方案将完全构建,否则您将遇到很多错误,以至于很明显,更改是如此具有侵入性,以至于真正掌握效果的唯一方法是开始真正尝试。

这种方法的好处是您可以进行级联而不需要实际处理如何处理它,只需您需要并粗略评估它是否会触发后续更改。一旦你很高兴你已经映射了更改,你就会在你的 IDE 中有一个现成的警告列表,可以在你正确更改界面时进行更改(并且构建确实失败了)。

这依赖于不将警告视为错误,您可能不得不暂时放松构建设置。

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

于 2009-01-28T22:32:15.477 回答
1

就像一个提示:当您要构建自己版本的此类工具时,您也可以使用反射对已编译的程序集执行此操作。

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

(注意:您不会直接使用反射获得的是程序集依赖于动态加载的程序集,例如通过 Assembly.Load 加载。如果在您的项目中使用它,则必须实现特殊处理)

于 2009-01-28T22:38:01.673 回答
0

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

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

于 2009-01-28T20:54:15.877 回答