2012-06-18 18 views
5

Programmierer in meinem Team öffnen manchmal eine Transaktion und vergessen, die Anweisung scope.Complete() einzufügen (siehe Codeblock unten). Alle Ideen, Möglichkeiten, um entwederC# - Wie überprüfe ich nach fehlenden scope.Complete() Anweisungen?

(1) in unsere Lösung scope.Complete für fehlende() Aussagen oder

(2) haben Visual Studio automatisch markieren oder eine Warnung für fehlende scope.Complete() Aussagen erhöhen ?

Hier ist die Linie, die wir vermissen:

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

Was ich
 
versucht habe, ich habe versucht, zu diesem Zweck ein ReSharper benutzerdefinierten Muster verwenden, ohne Glück. Idealerweise würde ich für etwas suchen, wie:

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

akzeptiert jedoch nur ReSharper reguläre Ausdrücke für Bezeichner, nicht für Aussagen, so scheint dies nicht zu funktionieren (http://www.jetbrains.com/resharper/webhelp/Reference__Search_with_Pattern.html).

Irgendwelche Ideen? Ich bin offen für die Verwendung anderer Plugins oder Tools.

Danke,
Ben

+1

Sie testen ihren Code nicht? – Magnus

+0

Ich habe das vorher mit einem Test gesehen. Über die Reflektion können Sie feststellen, ob eine Methode für eine Instanz aufgerufen wird. Wenn es nicht ist, schlägt der Test fehl. –

+1

Ich rechne mit NDepend, dass Sie eine Regel einrichten könnten, um nach Methoden zu suchen, bei denen die Anzahl der "TransactionScope" -Ctor-Verwendungen geringer ist als die Anzahl der 'Complete'-Verwendungen. – AakashM

Antwort

3

NDepend kann sicherlich helfen, aber kann nicht überprüfen, zu 100% von dem, was Sie fordern. NDepend kennt die Interna des Methodenrumpfs nicht (Reihenfolge der Methodenaufrufe). Also am besten können Sie ein code rule over LINQ (CQLinq) schreiben, die prüfen, ob, wenn ein Verfahren ein TransactionScope erstellen, zumindest es TransactionScope.Complete() nennen muss:

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

Beachten Sie, dass, wenn Entwickler diszipliniert genug, um mehr zu schaffen zu vermeiden TransactionScope in einem Verfahren , sollte diese Regel für Sie arbeiten.

+0

Ausgezeichnet. Vielen Dank! –

4

Könnten Sie Programmierer zwingen, eine benutzerdefinierte API anstelle der Low-Level-scope.Complete Sachen zu benutzen?

Verschluss wird Verwendung von .Complete() erzwingen:

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

Dann könnten Sie tun:

new TransactionScope().Do(() => /* Transactional stuff */); 
+0

Danke für die Antwort! Das stimmt, wir könnten unsere bestehenden Transaktionen umgestalten, um eine benutzerdefinierte API zu verwenden, die der von Ihnen geschriebenen ähnelt, und dann versuchen, Programmierer dazu zu zwingen, diese API für zukünftigen Code zu verwenden. Ich denke, der schwierige Punkt wäre die Umgestaltung aller Transaktionen, da wir bereits eine große Codebasis haben. Ich bin nicht sicher, ob das die Zeit wert wäre. Nachdenken darüber ... –

0

Mir ist kein vorhandenes R # -Plugin bekannt, das dies überprüft, aber Sie könnten sicherlich eines Ihrer eigenen erstellen. Sie müssen lediglich eine using-Anweisung mit einer Variablendeklaration des Typs TransactionScope erkennen und anschließend die enthaltenen Anweisungen durchlaufen, um nach dem Aufruf Complete() zu suchen.

Wenn Sie interessiert sind, empfehle ich Ihnen, die ReSharper SDK herunterladen und überprüfen Sie die Plugin Development Guide.