2010-08-05 20 views
2

當我在我的WPF控件項目上啓用代碼契約時,遇到了在編譯時創建的自動生成文件(XamlNamespace.GeneratedInternalTypeHelper)的問題。請注意,生成的文件稱爲GeneratedInternalTypeHelper.g.cs,與GeneratedInternalTypeHelper.g.i.cs不同,後者有幾個過時的博客文章。代碼合同和自動生成的文件

我不完全確定它的目的是什麼,但我認爲解決XAML的一些內部反射很重要。問題在於它沒有代碼合同,代碼合同系統也不夠智能,無法將其識別爲自動生成的文件。這導致來自靜態檢查器的一堆錯誤。

我試着尋找這個問題的解決方案,但似乎沒有人正在開發WPF控件和使用代碼合同。我遇到了一個有趣的屬性ContractVerificationAttribute,它採用一個布爾值來設置程序集或類是否被驗證。這可以讓你裝飾一個未驗證的類。不幸的是,每次編譯都會重新生成GeneratedInternalTypeHelper,所以不可能只排除這一個類。反過來,情況是可能的,但裝飾未經驗證的大會,然後選擇每個班級。

爲了減輕明顯的黑客我想創建一個測試,至少會驗證暴露類有代碼合同驗證與測試,如以下,以確保自己的類都至少被驗證:

[Fact] 
public void AllAssemblyTypesAreDecoratedWithContractVerificationTrue() 
{ 
    var assembly = typeof(someType).Assembly; 
    var exposedTypes = assembly.GetTypes().Where(t=>!string.IsNullOrWhiteSpace(t.Namespace) && t.Namespace.StartsWith("MyNamespace") && !t.Name.StartsWith("<>")); 

    var areAnyNotContractVerified = exposedTypes.Any(t => 
    { 
     var verificationAttribute = t.GetCustomAttributes(typeof(ContractVerificationAttribute), true).OfType<ContractVerificationAttribute>(); 
     return verificationAttribute.Any() && verificationAttribute.First().Value; 
    }); 

    Assert.False(areAnyNotContractVerified); 
} 

正如你所看到的,它需要控制程序集中的所有類,並從公司名稱空間中找到不是自動生成的匿名類型的類(<> WeirdClassName)。

(我還需要排除資源和設置,但我希望你明白了)。

我不喜歡解決方案,因爲有避免合同驗證的方法,但目前這是我能想到的最好方法。如果有人有更好的解決方案,請讓我知道。

+0

對此https://connect.microsoft.com/VisualStudio/feedback/details/483730/code-analysis-does-not-exclude-wpf-generated-files的一些評論建議進入代碼分析選項卡,取消選中並重新檢查「生成的代碼抑制結果」並重試。顯然這是VS2010本身的問題,而不僅僅是CC。 – porges 2011-01-19 10:13:28

回答

0

因此,您可以像對待任何其他「第三方」課程或圖書館一樣對待此課程。我相信某些假設會與交互點上的這個生成的類交互,所以在Contract.Assume(result != null)或類似的地方裝飾你自己的代碼。

var result = new GennedClass().GetSomeValue(); 
Contract.Assume(result != null); 

這樣做是翻譯成在運行時檢查斷言,但它允許靜態分析來思考,你做控制代碼的其餘部分。