2014-09-02 40 views
13

在過去的幾個月中,我一直在爲我的公司開發一個副項目,但是現在的高層們已經認定它適合現有的產品。我是否可以將代碼合併到我正在與非代碼合同開發人員使用的代碼庫合併的代碼中?

我一直在開發使用微軟的代碼合同靜態類型檢查(部分原因是因爲我沒有使用過他們,渴望學習)的側項目。

我的問題是,如果我在我的代碼檢查與地方的合同代碼庫,將所有其他開發者需要安裝能夠繼續開發代碼契約工具?我知道一個事實,他們都沒有安裝它,我在這裏是小三,所以我懷疑我可以說服他們都接受它。

我使用的是.Net 4.5,所以包含代碼合同庫,但我想知道如果Visual Studio會抱怨他們沒有在構建選項中指定的CONTRACTS_FULL每次他們去構建,或者,如果我在構建選項中保留CONTRACTS_FULL,另一個開發人員嘗試構建時會發生什麼?此外,我想知道當合同失敗時最終產品將如何行事,但代碼並未使用代碼合同重寫器構建。

我用一個項目創建了一個新的解決方案。創建了一個簡單的函數,解除代碼合同違約,代碼合同被卸載,並且未指定CONTRACTS_FULL。建立並運行它,並收到以下錯誤:

Run-time exception (line 8): An assembly (probably "hdxticim") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.Requires<TException> and the CONTRACTS_FULL symbol is defined. Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild. CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. 
After the rewriter is installed, it can be enabled in Visual Studio from the project's Properties page on the Code Contracts pane. Ensure that "Perform Runtime Contract Checking" is enabled, which will define CONTRACTS_FULL 

我認爲錯誤消息需要重寫,因爲CONTRACTS_FULL絕對沒有指定。

感謝MatíasFidemraizer,我們發現在使用Contract.Requires<TException>()而不是Contract.Requires()時發生這種情況。

理想情況下,我想修改此行爲使合同的觸發提供的異常,好像它是一個普通保護語句而不是抱怨重寫。

Here's a fiddle證明了問題:https://dotnetfiddle.net/cxrAPe

+0

我完全不理解這個問題。沒有安裝CC的開發人員不會使用*合約編譯整個解決方案*。合同將被忽略,建成的結果將不會有合同。 – 2014-09-09 15:49:42

+0

我收到一個錯誤'代碼合約重寫器尚未在此項目上運行,但它指定了CONTRACTS_FULL ...'抱怨合同未由合同重寫器在合同失敗時重寫,如果它沒有安裝工具。相反,我寧願它拋出在我的'Contract.Requires '調用中指定的異常。我只能假設我的團隊的其他成員會注意到這一點,而且我必須爲了最終版本而構建它。 – 2014-09-09 15:55:01

+0

如果您沒有CC VS擴展名,CC將無法編譯。自.NET 4.0起,.NET Framework中包含'Contract'類,但是它們在未安裝CC的情況下被繞過。 – 2014-09-09 17:26:20

回答

4

簡短的回答是:是的。如果使用代碼合同簽入代碼,則所有可能構建該代碼的開發人員必須安裝代碼合同才能構建代碼。

與@CBauer在他的回答中所寫的相反,代碼合約有一個「祝福」包。不,它不是NuGet軟件包—它是基於MSI安裝程序的安裝。最後,如果您處於持續集成環境以進行調試構建(例如開發,質量保證/質量控制和/或測試),那麼這些構建服務器還需要安裝代碼合同。

當您使用代碼合同時,調試版本始終需要使用代碼合同。請注意,這是不一定的情況下爲版本建立。這取決於您使用何種形式的合同檢查以及項目屬性中指定的選項。

Code Contracts manual有所有的細節。這非常好,我強烈建議花時間閱讀和理解它。

應當注意的是,如果你使用Contract.Requires<TException>(bool condition)形式的先決條件,你必須已經爲啓用代碼契約發行構建(見第5部分:使用指南,具體而言,第20頁用法2情景)。

因爲你是整合這個代碼到尚未開發出代碼契約現有的代碼庫,你應該考慮修改您的代碼契約項目屬性設置,以符合使用場景3概述了第20頁守則合同手冊「,並使用」遺留「if-then-throw模式重新制定合同。這將使您的團隊能夠最佳地篡改代碼庫,以便隨處使用代碼合同,允許您最終用實際代碼合同Contract.Requires(bool condition)檢查替換「遺留」前提條件前檢查,如果您願意,還可以使用Contract.Requires<TException>(bool condition)檢查。

更新:很快就會成爲代碼合同的NuGet包 我今天在新的GitHub代碼合同倉庫中。對於那些不瞭解你的人,微軟已經開源了,現在它是一個社區驅動的工作。

他們最近(回到1月份)宣佈v1.10.xxxx.RC1發佈。你可以找到關於它的信息here on their GitHub repository

4

可惜這很難保持未通過的NuGet最新的不強迫你的同事保持自己的個人環境中安裝了一個圖書館。代碼合同似乎沒有一個官方微軟支持的軟件包供用戶使用。下面

fourpastmidnight的帖子有最近更新的答案,我原來上面的關注,但是下半部分,我認爲即使是現在仍然是相關的。讓你的買進,人們!

在我的(當然主​​觀的)經驗,這樣的工具來,如果買入沒有同事間的預先設立一個唾罵。你可能會試着慢慢地討論這個問題,看看他們是否願意使用它。如果沒有安裝,無論設置CONTRACTS_FULL與否的代碼重寫合同,

+3

+1表示堅持。 「我在這裏是小三,所以我懷疑我可以說服他們:」OP不應該將他的建議的結果建立在他的資歷基礎上。作案,討論使用圖書館的利弊。程序員傾向於同意在決策中包含最佳路徑,提交所有事實並充分考慮它。 – 2014-09-09 14:58:48

0

Contract.Requires<TException>()將失敗。

一個解決方案是構建一個單獨的類FailableContract,它測試代碼合同設置的預處理器條件CONTRACTS_FULL

然後你所要做的就是記住在將你的代碼提交給代碼庫之前,從構建參數中刪除CONTRACTS_FULL。你仍然得到代碼合同,其他人都會得到警戒聲明。

FailableContract一小部分(我還在寫):

public class FailableContract 
{ 

    public static void Requires(bool condition) 
    { 
     #if CONTRACTS_FULL 
      Contract.Requires(condition); 
     #else 
      if (!condition) throw new ArgumentException(); //Just go with an argument exception because we haven't been supplied with an exception type. 
     #endif 
    } 

    public static void Requires<TException>(bool condition) where TException : Exception, new() 
    { 
     #if CONTRACTS_FULL 
      Contract.Requires<TException>(condition); 
     #else 
      if (!condition) throw new TException(); 
     #endif 
    } 
} 

然後一個簡單的查找,替換Contract.FailableContract.應該得到大多數問題。

+0

不,我想*不*拋出異常或合同異常。沒有CC重寫器==少檢查。如果部署是通過持續集成完成的,並且已部署的編譯通過CC編譯,那麼每個開發人員都將決定更容易:使用更多時間並獲得更多問題(從而降低生產力)或者僅安裝######2 @ ~~ @ @ CC延長(2分鐘...)然後離開 – 2014-09-10 13:46:20