2016-01-10 3 views
1

У меня есть проект. В этом проекте я использую кодовые контракты для .NET. Я установил Runtime Checking = true. . Но во время выполнения У меня есть ContractException:Сборка не переписана ccrewriter, хотя Runtime Checking = true

Exception брошенную: 'System.Diagnostics.Contracts.ContractException' в mscorlib.dll

Дополнительная информация: сборка (вероятно, "Общие") должен быть переписан используя двоичный перезаписывающий код кодовых контрактов (CCRewrite), потому что вызывается Contract.Ensures и символ CONTRACTS_FULL - . Удалите все явные определения символа CONTRACTS_FULL из вашего проекта и перестройте. CCRewrite можно загрузить с http://go.microsoft.com/fwlink/?LinkID=169180.

После установки перезаписывающего устройства его можно включить в Visual Studio на странице свойств проекта на панели «Контракты кода». Убедитесь, что активирован «Выполнение проверки выполнения времени выполнения», который будет определять CONTRACTS_FULL Причина исключения не в том, что условие не выполняется, но сборка не переписывается. Ccrewriter установлен, у меня нет проблем с другими проектами.

код, где это происходит:

Contract.Ensures(_instance != null && _instance._authData != null); 

Этот код не переписан так он выполняет в начале процедуры.

Я знаю, что есть обходное решение, чтобы просто использовать событие postbuild для выполнения ccrewrite, но я бы хотел его избежать.

В чем причина такого поведения? Как я могу проверить, был ли ccrewrite даже вызван? Я не вижу никакой информации в моем выпуске сборки.

ответ

1

Похоже, что это ошибка в CC. Я нашел странный workaroud:

Csproj файл моего проекта был отредактирован руки раньше, так что это был раздел с тегом и codecontracts настройки signAssebly:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> 
    <SignAssembly>true</SignAssembly> 
</PropertyGroup> 
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> 
    <SignAssembly>false</SignAssembly> 
    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> 
    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> 
    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers> 

    .... 

    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel> 
    <CodeContractsReferenceAssembly>DoNotBuild</CodeContractsReferenceAssembly> 
    <CodeContractsAnalysisWarningLevel>3</CodeContractsAnalysisWarningLevel> 
    <RunCodeAnalysis>false</RunCodeAnalysis> 
</PropertyGroup> 

Так что я переехал CodeContracts установки в той части, где она обычно хранится;

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> 
    <PlatformTarget>AnyCPU</PlatformTarget> 
    <DebugSymbols>true</DebugSymbols> 
    <DebugType>full</DebugType> 
    <Optimize>false</Optimize> 
    <OutputPath>bin\Debug\</OutputPath> 
    <DefineConstants>DEBUG;TRACE</DefineConstants> 
    <ErrorReport>prompt</ErrorReport> 
    <WarningLevel>4</WarningLevel> 
    <Prefer32Bit>false</Prefer32Bit> 
    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> 
    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> 
    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure> 

    .... 

    <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly> 
    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel> 
</PropertyGroup 

И теперь это работает. Я думал, что нет больших различий, где размещать разделы, и это имеет значение только для целей сборки.

Если кто-то может объяснить, почему это происходит, я повторю ответ.