禁止在外部代码中调用任意函数/类


12

我曾遇到过一些案例,其中有必要限制外部库和框架的API的访问,以防止对系统造成负面影响。

例如,在SharePoint应用程序中,调用spList.Items.GetItemById以获取列表项似乎很自然,即使是在循环中,也可能没有意识到这会导致巨大的性能问题。

也可能是我们需要禁止使用SmtpClient,以迫使每个人都使用我们自己的类来发送电子邮件,以确保我们可以在测试环境中正确代理和模拟所有电子邮件。

除了在我们自己的代码中的某些特定位置之外,是否有任何可靠且合理直接的方法来实现对外部代码的这些约束?不必绝对在每种情况下都禁止访问这些方法/类,例如通过反射或仅通过某种禁用来禁止访问,而应该严格警告不要使用它们。优选地,如果可能/需要,迫使程序员积极采取措施来克服这些约束。


11
这听起来像是一种极端形式的编码样式的强制执行(禁止使用特定的库调用)。所以对我来说,这提出了先决条件:您是否首先进行代码审查或样式检查?
彼得M,

3
您是否希望在运行时编译捕获并阻止这些调用?
MetaFight

1
由于您使用的是C#,您是否听说过StyleCop?您知道可以随意创建自定义规则,对吗?
马查多

10
除了在我们自己代码中的某些特定位置之外,是否有任何可靠且合理直接的方法来实现对外部代码的这些约束? ”。是:编写您自己的Roslyn Analyzer,以报告对某些API的访问作为编译错误。
David Arno

3
@ Machado,StyleCop实际上是无效的产品。它被替换为基于Roslyn的StyleCopAnalyzers。如今,花时间去编写自定义StyleCop规则绝对不是一个好主意。
David Arno

Answers:


8

除了在我们自己的代码中的某些特定位置之外,是否有任何可靠且合理直接的方法来实现对外部代码的这些约束?

由于问题专门针对C#,因此存在一种基于编译器的解决方案,可以在其中使用以执行此类规则:Roslyn Analyzers。您可以编写自己的分析器,以报告对某些API的访问为编译错误或警告。

StyleCop Analyzers是一组分析器的示例,它们提供了许多自己编写的示例代码,它们替代了C#的旧StyleCop功能。

话虽如此,这样的自动检查总是可以由决心“违反规则”的人们来解决。因此,这种方法不能替代Karl Bielefeldt的答案中讨论的代码审查。它可以帮助进行此类检查,但不应替换它们。


从来没有打算替换任何其他东西,我只是在为我的工具箱寻找专用工具。
亚历克斯(Alex)

25

您可以进行一些耗时的工作,例如围绕外部API编写包装程序,从而避免了不必要的操作,但是没有什么比培训和代码审查更胜一筹了,因为无论您采用了哪种标准或技术措施,人们都会找到创造性的方法来解决这些问题。

例如,我们有一些用Scala编写的服务,并且在代码审查时我们要求的一件事是不可变性,但是我们通常会在摆脱时进行交流vars。前几天有人使用val x:ListBuffer [Boolean]将单个可变变量保存为列表中的唯一项。您不能ListBuffer为x 分配另一个,但是您可以根据需要尽可能多地替换列表中的项目。就像使用var,但更加狡猾一样糟糕。

换句话说,您必须检查是否有人在使用您的技术解决方案。如果这些技术解决方案成本高昂并增加了复杂性,则最好检查一下它们是否正确编码。


该死的是偷偷摸摸的!
WHN

@snb等效于Java的破解,它只能返回一个对象/值并且没有适当的引用参数。传递一个数组来更新其内容。(一些示例:AtomicMarkableReference.getAtomicStampedReference.get)。
JAB

感谢您的回答,但我绝对不愿意执行耗时的复杂事情,例如围绕外部代码编写包装器。那可能甚至没有帮助,因为他们可以直接找到源头。这个答案似乎假设解决方案是昂贵的并且增加了复杂性。单纯的解决方案呢?
亚历克斯(Alex)

1
@Alex最简单的解决方案就在这里:“没有什么比培训和代码审查更好”。
Mindor先生,2017年

2
除非有人将其自动化,否则“手动操作无与伦比”是正确的。
伊万(Ewan)

0

卡尔的答案是100%正确的。没有办法保证一致性。但是,除了培训和代码审查之外,请考虑使用静态分析工具来确保合规性。(注意:我说“除了”,因为也可以用与Karl所述完全相同的方式绕过它们)。

使用静态分析工具的优点是,消除了繁琐的人工代码分析,以查找“多次使用IEnumerable”的实例,或者您正在查看的一周中的任何性能问题(或者至少,我始终觉得自己在看着)。这将使代码审查和培训专注于更多“有趣”的问题。

具体来说,对于C#,我在下面提供了一些建议。将它们插入您的构建环境中,您就可以开始了。但是,通常,无论您使用哪种语言,都在某处有一个静态分析工具。

直接从Wikipedia页面复制/粘贴,使用Wiki页面获取最新信息和链接:https : //en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#.NET

  • .NET编译器平台(代号Roslyn)–由Microsoft .NET开发的C#和Visual Basic .NET的开源编译器框架。提供用于分析和处理语法的API。
  • CodeIt.Right –将静态代码分析和自动重构结合到最佳实践中,从而可以自动纠正代码错误和违规;支持C#和VB.NET。
  • CodeRush – Visual Studio的插件,可提醒用户违反最佳实践。
  • FxCop –编译为CIL的Microsoft .NET程序的免费静态分析。独立并集成在某些Microsoft Visual Studio版本中;由Microsoft。
  • NDepend –通过分析和可视化代码依赖关系,定义设计规则,进行影响分析以及比较不同版本的代码,简化了对复杂.NET代码库的管理。集成到Visual Studio中。
  • Parasoft dotTEST –用于Visual Studio的静态分析,单元测试和代码审查插件;适用于Microsoft .NET Framework和.NET Compact Framework的语言,包括C#,VB.NET,ASP.NET和Managed C ++。
  • Sonargraph –支持C#,Java和C / C ++,重点在于依赖性分析,自动体系结构检查,指标以及添加自定义指标和代码检查器的功能。
  • StyleCop –分析C#源代码以实施一组样式和一致性规则。它可以从Microsoft Visual Studio内部运行,也可以集成到MSBuild项目中。

-1

要详细说明在另一个答案中提出的“培训和代码审查”建议:由于您希望禁止的代码是合法代码,因此您不能指望编译器阻止它,而您必须依靠以后的过程,评价。

这可以(并且应该)包括手动和自动检查步骤:

  • 准备一份已知问题的清单,并在您的手动代码审核中逐一进行检查。召开一次定期会议以检查和更新清单。每当发现并分析令人讨厌的错误时,请将其添加到清单中。

  • 添加签入规则以查找已知模式。编写起来可能很复杂,但是随着时间的推移,对于大型项目而言,它可能会很有用。TFS允许您用C#编写规则,其他构建系统也有其自己的钩子。考虑使用门控构建拒绝与模式匹配的签入。是的,它减慢了开发速度,但是在一定的项目规模和复杂度之后,放慢开发人员的速度可能是一件好事。


-1

也许编译器可以帮助您捕获不需要的调用。

重命名您自己的lib中不应由外部lib客户端使用的代码的类/方法。或者,将类/方法设置为内部,并向允许使用它们的类添加内部可见的对象。

外部lib用户将获得未找到的编译错误方法/类。

公共库中的禁止类/方法:在您的库中创建相同的名称空间/类/方法

外部lib用户将由于发现重复的类而获得编译错误

[更新]

不必绝对在每种情况下都阻止对这些方法/类的访问,例如通过反射或只是某种禁用来...。

如果可能/需要,迫使程序员(... lib的客户端...)积极采取措施来覆盖这些约束。


对此表示不满,不仅是因为它是一个讨厌的黑客,而且还可以使用extern别名轻松地将其与C#(OP为该问题添加了标签)一起使用。
David Arno
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.