2012-06-18 51 views
5

Các lập trình viên trong nhóm của tôi đôi khi mở một giao dịch và quên bao gồm câu lệnh scope.Complete() (xem khối mã bên dưới). Bất kỳ ý tưởng về cách để một trong haiC# - Làm cách nào để kiểm tra các câu lệnh scope.Complete() bị thiếu?

(1) tìm kiếm giải pháp của chúng tôi cho thiếu scope.Complete() tuyên bố, hoặc

(2) có Visual Studio tự động làm nổi bật hoặc nâng cao một cảnh báo cho thiếu scope.Complete() báo cáo ?

Đây là dòng chúng tôi bỏ lỡ:

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

Những gì tôi đã cố gắng
 
Tôi đã cố gắng sử dụng một mẫu ReSharper Tuỳ chỉnh cho mục đích này, không có may mắn. Lý tưởng nhất là tôi sẽ tìm kiếm một cái gì đó như:

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

Tuy nhiên, ReSharper chỉ chấp nhận biểu thức thông thường để định danh, không cho phát biểu, vì vậy đây không xuất hiện để làm việc (http://www.jetbrains.com/resharper/webhelp/Reference__Search_with_Pattern.html).

Bất kỳ ý tưởng nào? Tôi cũng đang mở để sử dụng các plugin hoặc công cụ khác.

Cảm ơn,
Bến

+1

Họ không kiểm tra mã của họ? – Magnus

+0

Tôi đã nhìn thấy điều này trước khi thực hiện kiểm tra. Qua phản xạ, bạn có thể xác định xem một phương thức có được gọi trên một cá thể hay không. Nếu không thì thử nghiệm sẽ thất bại. –

+1

Tôi nghĩ với NDepend bạn có thể thiết lập một quy tắc để tìm kiếm các phương thức mà số lượng tập quán ctor 'TransactionScope' ít hơn số lượng' Hoàn thành' tập quán. – AakashM

Trả lời

3

NDepend chắc chắn có thể giúp đỡ, nhưng không thể kiểm tra 100% những gì bạn đang yêu cầu. NDepend không biết về phương thức body internals (thứ tự gọi phương thức). Vì vậy, tốt nhất, bạn có thể viết một code rule over LINQ (CQLinq) rằng sẽ kiểm tra xem nếu một phương pháp đang tạo ra một TransactionScope, ít nhất nó phải gọi TransactionScope.Complete():

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

Lưu ý rằng nếu các nhà phát triển đang xử lý kỷ luật, đủ để tránh tạo ra nhiều TransactionScope trong một phương pháp , quy tắc này sẽ phù hợp với bạn.

+0

Tuyệt vời. Cám ơn rất nhiều! –

4

Ông có thể buộc các lập trình viên sử dụng một API tùy chỉnh thay vì những thứ scope.Complete cấp thấp?

Một đóng cửa sẽ buộc sử dụng .Complete():

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

Sau đó, bạn có thể làm:

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

Cảm ơn bạn đã trả lời! Đó là sự thật, chúng tôi có thể cấu trúc lại các giao dịch hiện tại của chúng tôi để sử dụng API tùy chỉnh tương tự như API bạn đã viết và sau đó cố gắng buộc các lập trình viên sử dụng API này cho mã trong tương lai. Tôi nghĩ điểm khó khăn sẽ là tái cấu trúc tất cả các giao dịch, vì chúng tôi có một cơ sở mã lớn. Tôi không chắc liệu điều đó có xứng đáng với thời gian liên quan hay không. Suy nghĩ về nó ... –

0

Tôi không biết bất kỳ plugin R # hiện có nào để kiểm tra điều này, nhưng bạn chắc chắn có thể tạo một trong số của riêng bạn. Tất cả những gì bạn phải làm là phát hiện một câu lệnh bằng cách sử dụng một khai báo biến kiểu TransactionScope, sau đó lặp lại các câu lệnh có chứa tìm kiếm cuộc gọi Complete().

Nếu bạn quan tâm đến việc này, tôi khuyên bạn nên tải xuống ReSharper SDK và kiểm tra Plugin Development Guide.

Các vấn đề liên quan