5

我团队中的程序员有时会打开事务并忘记包含 scope.Complete() 语句(参见下面的代码块)。关于方法的任何想法

(1) 在我们的解决方案中搜索缺少的 scope.Complete() 语句,或者

(2) 是否让 Visual Studio 自动突出显示丢失的 scope.Complete() 语句或发出警告?

这是我们错过的那一行:

 using(TransactionScope scope = new TransactionScope())
 {
      /* Perform transactional work here */
      scope.Complete(); <-- we forget this line
      /* Optionally, include a return statement */
 }

我已经尝试
 
过为此目的使用 ReSharper 自定义模式,但没有成功。理想情况下,我会搜索以下内容:

using(TransactionScope scope = new TransactionScope())
{
    $statements1$
    [^(scope.Complete();)]
    $statements2$
}

但是,ReSharper 只接受标识符的正则表达式,而不是语句,因此这似乎不起作用 ( http://www.jetbrains.com/resharper/webhelp/Reference__Search_with_Pattern.html )。

有任何想法吗?我也愿意使用其他插件或工具。

谢谢,

4

3 回答 3

4

你能强迫程序员使用自定义 API 而不是低级范围。完整的东西吗?

闭包将强制使用.Complete()

public static void Do(this TransactionScope scope, Action action) {
  using (scope) {
    action();
    scope.Complete();
  }
}

然后你可以这样做:

new TransactionScope().Do(() => /* Transactional stuff */);
于 2012-06-18T14:26:01.980 回答
3

NDepend 当然可以提供帮助,但无法检查 100% 的您所要求的内容。NDepend 不知道方法体内部结构(方法调用的顺序)。因此,充其量,您可以在 LINQ (CQLinq)上编写一个代码规则,该规则将检查一个方法是否正在创建一个TransactionScope,至少它必须调用TransactionScope.Complete()

warnif count > 0
from m in Application.Methods
where m.CreateA("System.Transactions.TransactionScope") &&
     !m.IsUsing("System.Transactions.TransactionScope.Complete()")
select m

请注意,如果开发人员有足够的纪律性来避免TransactionScope在一个方法中创建多个,则此规则应该适合您。

于 2012-06-19T12:31:44.530 回答
0

我不知道有任何现有的 R# 插件可以对此进行检查,但您当然可以创建自己的一个。您所要做的就是检测带有TransactionScope类型变量声明的 using 语句,然后迭代包含的语句以查找Complete()调用。

如果您对此感兴趣,我建议您下载ReSharper SDK并查看插件开发指南

于 2012-06-19T14:42:53.370 回答