【问题标题】:Assembly is not rewritten by ccrewriter even though Runtime Checking = true即使运行时检查 = true,ccrewriter 也不会重写程序集
【发布时间】:2016-01-11 06:22:07
【问题描述】:
我有一个项目。在这个项目中,我使用 .NET 的代码合同。我设置运行时检查 = true。 。但在运行时我有一个 ContractException:
抛出异常:'System.Diagnostics.Contracts.ContractException' in
mscorlib.dll
附加信息:程序集(可能是“Common”)必须是
使用代码契约二进制重写器 (CCRewrite) 重写,因为
它正在调用 Contract.Ensures 并且 CONTRACTS_FULL 符号是
定义。删除 CONTRACTS_FULL 符号的任何显式定义
从你的项目中重建。 CCRewrite 可以从
http://go.microsoft.com/fwlink/?LinkID=169180。
重写器安装后,可以在Visual Studio中启用
从项目的“代码合同”窗格上的“属性”页面。确保
启用“执行运行时合同检查”,这将定义
合同满
异常的原因不是条件不满足,而是程序集没有重写。 Ccrewriter 已安装,我在其他项目上没有问题。
发生的代码:
Contract.Ensures(_instance != null && _instance._authData != null);
此代码未重写,因此它在过程开始时执行。
我知道有一种解决方法可以只使用 postbuild 事件来执行 ccrewrite,但我想避免它。
这种行为的原因是什么?如何检查是否调用了 ccrewrite?我在构建输出中看不到任何信息。
【问题讨论】:
标签:
.net
visual-studio
code-contracts
【解决方案1】:
看起来这是 CC 中的一个错误。我发现了一个奇怪的解决方法:
我的项目的 Csproj 文件之前是手工编辑的,所以它有带有 signAssebly 标签和 codecontracts 设置的部分:
<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
现在它可以工作了。我认为在哪里放置部分没有太大区别,它只对构建目标很重要。
如果有人可以解释为什么会发生,我会重新接受答案。