Getting started
Add Contracts NuGet package
This package is available on NuGet: PPWCode.Vernacular.Contracts.I.
You can use your IDE to add it as a dependency of your project, or manually add it in the .csproj file. This might look like the following:
<Project Sdk="Microsoft.NET.Sdk">
<!-- ... -->
<ItemGroup>
<!-- nuget package dependencies -->
<PackageReference Include="PPWCode.Vernacular.Contracts.I" Version="1.2.0" />
</ItemGroup>
<!-- ... -->
</Project>
After the package is added, you can use PPWCode.Vernacular.Contracts.I in your code. Notably, the following statements become available:
-
Contract.Requires(…) -
Contract.Ensures(…) -
Contract.Invariant(…) -
Contract.Assert(…) -
Contract.Assume(…)
Define build constants
The different contract statements are annotated with the Conditional attribute and are only compiled in your code when the corresponding build constant is defined.
The following build constants are used:
-
CONTRACTS_PREforContract.Requires(…) -
CONTRACTS_POSTforContract.Ensures(…) -
CONTRACTS_INVARIANTforContract.Invariant(…) -
CONTRACTS_ASSERTforContract.Assert(…)andContract.Assume(…)
It is important that you enable these for your own code that uses PPWCode.Vernacular.Contracts.I. When they are defined, the run-time validation of the contract statements is active. When they are not defined, the built code will not include the run-time validation.
The build constants are used to provide some flexibility for the user. For example, it would be possible to define the constants for debug builds and omit them for release builds. This means that debug builds would include the run-time validation and release builds would not. Performance could be a reason to disable the run-time validation in release builds.
The constants must be defined for each project that uses the library (in each .csproj file). Alternatively, the constants could be defined in a Directory.Build.props which would be used by multiple projects.
In both cases, the configuration would look like the following:
<Project>
<!-- ... -->
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE;CONTRACTS_PRE;CONTRACTS_POST;CONTRACTS_INVARIANT;CONTRACTS_ASSERT;JETBRAINS_ANNOTATIONS</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE;CONTRACTS_PRE;CONTRACTS_POST;CONTRACTS_INVARIANT;CONTRACTS_ASSERT;JETBRAINS_ANNOTATIONS</DefineConstants>
</PropertyGroup>
<!-- ... -->
</Project>