【问题标题】:Discovering Interface Dependencies发现接口依赖
【发布时间】:2010-10-04 02:26:20
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

    标签: c# interface dependencies


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 您可以根据需要使用免费试用版。
      【解决方案3】:

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

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

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

      【讨论】:

      • 后续问题:有没有办法检查已编译的 DLL 并查看它调用的所有其他 dll?如果我们能获得方法名称和入口点,那就太好了。谢谢! -托德
      【解决方案4】:

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

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

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

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

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

      在新的源代码更新中执行所有这些操作,这样如果您想重试,只需回滚部分即可。

      【讨论】:

      • 好建议。然而,这更像是一种“蛮力”的方法。我希望在编译/构建之前找到一种方法来查看所有依赖项。
      • +1 从来不知道过时的标签有实际用途。以为是纯装饰性的
      【解决方案5】:

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

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

      【讨论】:

      • 2 个问题:1)当您谈到模块版本号时,您指的是 DLL/程序集版本吗?这听起来像是您在发布新版本时尝试进行构建,然后一次修复构建错误? 2)您第二段中的实用程序是本土工具吗?谢谢!
      • 我们是一家 Java 商店,所以版本号非常随意。版本号在模块的文件名中,例如 LoggingModule_1.01.01.jar。当模块有新版本时,不会出现构建错误,因为项目必须显式导入新版本。是的,它是本土种植的。
      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-28
        • 2015-10-18
        • 2011-04-12
        • 1970-01-01
        • 2020-10-09
        • 1970-01-01
        相关资源
        最近更新 更多