在C#中,如何将某些方法调用完全保留在代码库之外?
我试图摆脱所有DateTime.Now
方法调用,并用我自己的GetNow()
方法替换它们,有时可能会返回固定日期以进行测试。
如何强制执行以后没有人添加DateTime.Now
调用? 我可以使用NDepend或StyleCop在我的持续集成服务器上进行检查吗?
使用NDepend, 编写此规则非常容易:
// Forbid DateTime.Now, use xxx.GetNow() instead WARN IF Count > 0 IN SELECT METHODS WHERE IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"
注意:
- WARN IF Count> 0 IN的前缀可将CQL查询转换为规则
- 通过字符串System.DateTime.get_Now()引用属性的方式
- 前缀OPTIONAL表示“如果找不到属性get_Now,则不发出编译错误”。 这是有道理的,因为如果您的代码不再使用get_Now(),则不再从NDepend分析中引用它。
另外,要生成原始查询…
SELECT METHODS WHERE IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"
…只需右键单击DateTime.get_Now()并选择直接使用我的选择方法….
首先, DateTime.Now
是一个属性 。
这意味着您不需要在调用后放置括号。
其次,如果出于测试目的,您指的是像NUnit这样的框架,您可能需要查看Microsoft Moles ,它允许您在测试时用自己的自定义实现替换任何静态方法调用 。 哎呀,很酷:
[Test] [ExpectedException (typeof (Y2KBugException))] public void TestY2KBug () { MDateTime.NowGet = () => new DateTime (2001, 1, 1); Bomb.DetonateIfY2K (); } public static class Bomb { public static void DetonateIfY2K () { if (DateTime.Now == new DateTime (2001, 1, 1)) throw new Y2KBugException (); // take cover! } }
没有真正的方法来强制执行这样的事情。
你最接近的是制作一个自定义的FxCop规则或自定义的Visual Studio代码分析规则来对DateTime.Now的调用进行错误/警告。
您可以在测试中使用Moles在需要时提供您自己的DateTime.Now,而无需修改任何调用它的现有代码。
另一种选择可能是在编译后修改程序集以调用其他内容。 (也许,使用Mono.Cecil重写IL,并在VS中的后期构建中添加一个命令来运行它。)
您也许可以获取Mono源并自行构建一个自定义的mscorlib,并删除该function。
一种方法可能是在您选择的源控件存储库中添加预提交挂钩,以查找DateTime.Now
并在您找到有问题的字符串时中止签入。 它不是万无一失的,它可能会让你的同事烦恼,但它应该有助于它远离代码库。
我不认为这是可能的。 您实际上要做的是覆盖DateTime的结构function。
我能想到的唯一方法就是使用自定义类来包装DateTime的常用function并根据需要提供不同的function……