I have a project. In this project I'm using code contracts for .NET. I set Runtime Checking = true. . But at runtime I have a ContractException:
Exception thrown: 'System.Diagnostics.Contracts.ContractException' in mscorlib.dll
Additional information: An assembly (probably "Common") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.Ensures 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 The cause of the exception is not that condition doesn't fulfill, but that the assembly is not rewritten. Ccrewriter is installed, I don't have troubles with other projects.
The code where it happens:
Contract.Ensures(_instance != null && _instance._authData != null);
This code is not rewritten so it executes at the start of the procedure.
I know there is a workaround to just use postbuild event to execute ccrewrite, but I'd like to avoid it.
What can be the reason for such a behavior? How can I check if ccrewrite was even invoked? I don't see any information in my build output.
Looks like it is a bug in CC. I found a weird workaroud:
Csproj file of my project was edited by hands before, so it had section with signAssebly tag and codecontracts settings:
<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>
So I moved CodeContracts setting to the part where it is usually stored;
<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
And now it works. I thought there is no big differnce where to put sections, and it only matters for build targets.
If someone can explain, why it happens, I will reaccept the answer.