how to install and use Code Contracts? - c#

I have a basic question, might be it is so obvious but for some reason i can't seem to be successful with installing and using Code Contracts.
I've downloaded the package from MSDN, installed it following the online documentation but i still get an IDE warning for the below code statement:
Contract.Requires(inputParameter != "");
the IDE warning is:
"Method invocation is skipped. Compiler will not generate method invocation because the method is conditional, or it is partial method without implementation"
Anything I'm missing in the process of enabling Code Contracts? I'm using VS2010 Ultimate SP1

Most likely this is due to Code Contracts not being configured in the project settings. If you go to your project properties, you should see a Code Contracts tab. On the tab, select the mode you are building in (Debug|Release|Both) and then turn on Code Contracts features by checking the appropriate check boxes.
I've seen the warning that you detail when Code Contracts are not set to Build.
If you don't see the Code Contracts tab, then you might need to install Code Contracts on your machine. Do this by downloading and installing the installer from here.

Conditional compilation is all driven from compiler preprocessor definitions. This is the same approach used for the DEBUG constant, although Visual Studio hides the definition of that behind a checkbox. It's an efficient approach because when those symbols aren't defined then the methods aren't called at all; importantly the parameters being passed aren't evaluated either, so you can use relatively expensive checks in your code contracts without worrying about those checks slowing down release builds.
Microsoft's introduction to Code Contracts says this:
Most methods in the contract class are conditionally compiled; that is, the compiler emits calls to these methods only when you define a special symbol, CONTRACTS_FULL, by using the #define directive. CONTRACTS_FULL lets you write contracts in your code without using #ifdef directives; you can produce different builds, some with contracts, and some without.
Although this talks about using #define in the code to turn on code contracts:
#define CONTRACTS_FULL
as #NirMH said in the comments it's usually better to define it in the conditional compilation symbols for the project so you can have it on for some builds and off for others.
Note that CONTRACTS_FULL is the only option you have, although it's clearly been named to allow the possibility of more granular control in future.

Related

Can I leave contracts in code that I'm merging with a codebase used by non-code contracts developers?

For the last few months I've been developing a side project for my company, but the higher-ups have now decided it would be a good fit in an existing product.
I've been developing the side project using Microsoft's Code Contracts for static type checking (partly because I hadn't used them before and was eager to learn).
My problem is that if I check in my code to the code base with Contracts in place, will every other developer need the Code Contracts tools installed to be able to continue developing? I know for a fact that none of them have it installed, and I'm the junior here so I doubt I could convince them all to take it up.
I'm using .Net 4.5, so the Code Contract libraries are included, but I'm wondering if Visual Studio will complain that they're not building with CONTRACTS_FULL specified in the build options every time they go to build, or, if I leave CONTRACTS_FULL in the build options, what will happen when another developer tries to build? Additionally I'm wondering how the end-product will act when a Contract fails, but the code has not been built with the Code Contracts Rewriter.
I created a new solution with just one project. Created a simple function that fired a code contract violation, with code contracts uninstalled and CONTRACTS_FULL not specified. Built and ran it and received the following error:
Run-time exception (line 8): An assembly (probably "hdxticim") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.Requires<TException> 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
I think the error message needs rewriting, as CONTRACTS_FULL is most definitely not specified.
Thanks to Matías Fidemraizer, we've worked out that this happens when using Contract.Requires<TException>() and not on Contract.Requires().
Ideally, I'd like to modify this behaviour so that the Contract fires the provided exception as if it were a normal guard statement instead of complaining about the rewriter.
Here's a fiddle demonstrating the problem: https://dotnetfiddle.net/cxrAPe
The short answer is: Yes. If you check in the code with Code Contracts, then all developers that might build that code must also have Code Contracts installed in order to build the code.
In contradiction to what #CBauer wrote in his answer, there is a "blessed" package for Code Contracts. No, it's not a NuGet package—it's an MSI installer based installation.
Finally, if you are in a Continuous Integration environment for debug builds (e.g. Development, QA/QC and/or Testing), then those build servers will also need to have Code Contracts installed.
When you use Code Contracts, Debug builds always require the use of Code Contracts. Please note that this is not necessarily the case for Release builds. It depends on what form of contract checking you're using and the options specified in the Project Properties.
The Code Contracts manual has all the details. It's quite good and I highly recommend taking the time to read and understand it.
It should be noted that if you use the Contract.Requires<TException>(bool condition) form of preconditions, you must have Code Contracts enabled for Release builds (see Section 5: Usage Guidelines, specifically, page 20, Usage 2 scenario).
Since you are integrating this code into an existing codebase that has not been developed with Code Contracts, you should consider revising your Code Contracts Project Property settings to conform to Usage Scenario 3 outlined on page 20 of the Code Contracts manual, and reformulate your contracts using the "legacy" if-then-throw pattern. This will enable your team to best tranisition the code base to using Code Contracts everywhere, allowing you to eventually replace "legacy" if-then-throw precondition checks with actual Code Contracts Contract.Requires(bool condition) checks, and if you like, Contract.Requires<TException>(bool condition) checks.
UPDATE: There Will Soon Be A NuGet Package For Code Contracts
I was at the new GitHub repository for Code Contracts today. For those of you who don't know, Microsoft has open-sourced this and it is now a community-driven effort.
They recently (back in January) announced v1.10.xxxx.RC1 release. You can find information about it here on their GitHub repository.
Unfortunately it's difficult to keep a library that is not installed via nuget up to date without forcing your coworkers to maintain their personal environment. Code contracts does not appear to have an official Microsoft-blessed package out there for use.
fourpastmidnight's post below has a recently updated answer to my original concern above, but the bottom half I think remains relevant even now. Get your buy-in, people!
In my (admittedly subjective) experience, tools like this come to be reviled if buy-in is not established among coworkers in advance. You might try broaching the subject slowly to see if they would be receptive to using it.
Contract.Requires<TException>() will fail if the code contracts rewriter is not installed, regardless of setting CONTRACTS_FULL or not.
One solution is to build a separate class FailableContract which tests the preprocessor condition CONTRACTS_FULL, which is set by Code Contracts.
Then all you have to do is remember to remove CONTRACTS_FULL from your build parameters before committing your code to the code base. You still get code contracts, everybody else gets guard statements.
A small portion of FailableContract (which I'm still writing):
public class FailableContract
{
public static void Requires(bool condition)
{
#if CONTRACTS_FULL
Contract.Requires(condition);
#else
if (!condition) throw new ArgumentException(); //Just go with an argument exception because we haven't been supplied with an exception type.
#endif
}
public static void Requires<TException>(bool condition) where TException : Exception, new()
{
#if CONTRACTS_FULL
Contract.Requires<TException>(condition);
#else
if (!condition) throw new TException();
#endif
}
}
Then a simple Find, Replace Contract. to FailableContract.should get most issues.

Code Contracts - Visual Studio Team Service Scripted Build Server Unit Tests Fail

I recently added Code Contracts to my solution. After some modifications our build runs without any problems but our unit tests fail because of Code Contracts.
Environment:
Source control and build server are hosted on Visual Studio Team Service (VSTS) Scripted Build (formerly VSO)
VS 2013 Premium Code (now VS 2015 Enterprise) contracts enabled on configurations Debug and Release
Code contract turned off with DoNotBuild flag set for custom configurations BuildServer
Visual Studio Team Services build definition:
Has step Visual Studio
has flags set /p:CodeContractsEnableRuntimeChecking=false;CodeContractsReferenceAssembly=false
Example error text from build server:
Test method
Web.Tests.AccountControllerTests.CreateAccount_Pass_NoPasswordSend_Test
threw exception: System.Diagnostics.Contracts.ContractException: An
assembly (probably "Cms.Web") must be rewritten using the code
contracts binary rewriter (CCRewrite) because it is calling
Contract.Requires and the CONTRACTS_FULL symbol is
defined. Remove any explicit definitions of the CONTRACTS_FULL symbol
from your project and rebuild.
I have examined the diagnostic output from the build server and there is no symbol CONTRACTS_FULL that can be found anywhere.
I do not want to enable code contracts on the build server mostly because I had tried that before with no success and due to time constraints I gave up (after more searching I came to the conclusion that this is not possible as Microsoft does not allow for custom extensions to be installed on the build server). I simply want to ignore code contracts on the build server but the Unit Test execution does not seem to do this.
Any one have any ideas on where I need to look to ensure code contracts are ignored by the unit tests? Seems like this should be possible right? Maybe there is another flag I could set in the build definition that will be picked up by the unit tests?
Edit
Please note the build server is HOSTED in the cloud as a Microsoft service as a part of Visual Studio Team Services (formerly Visual Studio Online). This means it is not our build server, we have no control over what is installed on the build server. Even so we want to use Code Contracts. The accepted answer below is a way to allow for this.
Please, please read the Code Contracts manual. It tells you everything you need to know. You don't need any ConditionalAttribute defined on your methods. You can use Contract.Requires<TException>(bool condition) if you know what the requirements for doing so are.
As #Mixxiphoid said in their answer, because they were using the generic form of Requires, Code Contracts is required to be installed on the build server and Peform Runtime Contract Checking needs to be enabled for the Release configuration in addition to the Debug configuration.
If you are using Code Contracts, then you will always need Code Contracts installed on the build servers that build Debug releases. The same goes for your team: all developers who need to compile the code will be required to have Code Contracts installed for Debug builds.
It's all in Section 5: Usage Guidelines in the Code Contracts manual. There's a helpful diagram on page 20 that gives a great summary of the various usage scenarios and their requirements.
About Contract.Requires<TException>(bool condition)
First off, the developer that wrote this method for Code Contracts did not forget to apply the ConditionalAttribute to the method, as the accepted answer states. Far from it. The very fact that this method is not decorated with that attribute is by design.
If you read Section 5: Usage Guidelines, you see that if you use this form of the Requires method, then you are required to use the binary rewriter—ccrewrite—when building your assembly. This implies that any machine which will build your assembly must have ccrewrite available.
So, what about build servers that you may not control? I'm glad you asked.
TFS Hosted Build Servers
With respect to TFS hosted build servers: It's true that you cannot simply install Code Contracts on the build servers. So what are your options?
You could limit yourself to using only the "legacy" form of code contracts, if-then-throw blocks followed by Contract.EndContractBlock() or limit yourself to only using Contract.Requires(bool condition) (the non-generic form), or a mixture of the two.
In either case, you'll probably want to have a separate Debug build configuration for the TFS-hosted build server. This build configuration would have Perform Runtime Contract Checking disabled for that build configuration.
You could do a little "bing-ing" or "googling" and come up with this search result, which describes how to enable building your solution with Code Contracts on TFS Online.
The blog post linked to above has instructions for modifying a TFS Hosted Build Controller hosted build.
UPDATE: THERE WILL SOON BE A NUGET VERSION OF CODE CONTRACTS
For those of you using hosted build services, such as Visual Studio Online, AppVeyor, etc., the new community-driven Code Contracts GitHub repo recently announced v1.10.xxxxx.RC1. In the release notes, they mention a NuGet version of code contracts. Enjoy.
After double checking this build configuration also has the same errors in the unit test as on the build server. After some digging I came up with the answer.
The answer lies in Contract.Requires. The generic version of method Contract.Requires<T> does not apply the attribute [Conditional("CONTRACTS_FULL")] where as the non-generic method Contract.Requires does. This means that Contract.Requires<T> is always evaluated and there is nothing you can do about it. See Cutting Edge - Code Contracts Settings in Visual Studio 2010 for more detail.
After I reverted all of my code to make use of Contract.Requires instead of Contract.Requires<T> all my unit tests were able to execute again. You can still make use of ContractClassFor and ContractClass attributes and make use of the generic Contract.Requires<T> implementation within the contract class without any problem, this because the contract class will not get built without CONTRACTS_FULL.
Got the exact same problem this morning. The solution was to enable runtime contract checking on release mode instead of only debug mode.
Beside that, CodeContracts had to be installed on the build server as well.

How to undefine the symbol CONTRACTS_FULL?

Visual Studio defines the CONTRACTS_FULL symbol automatically if
you enable contract checking in the Code Contracts tab of the Project
Properties page.
- C# 5.0 In a Nutshell (page 518)
I'd like to disable/undefine the symbol but it doesn't appear in the Conditional compilation symbols field of the Build tab in the project settings.
(I'm not interested in disabling code-contracts completely! by that I simply mean that setting the contract checking to None is not a solution).
If it matters, the reason I want to do this is because in my release builds I only want to throw on Contract.Requires<TException>, and I don't want to throw ContractException at all.
One "solution" I found is to put #undef CONTRACTS_FULL at the first line of each file, it fixed it but actually doing that would be horrible.
(BTW up until now VS didn't define CONTRACTS_FULL and I had to define it myself, but I guess some setting changed accidentally)
You cannot run the contract tools and undefine the CONTRACTS_FULL symbol. The tools depend on that being defined. Nothing will work if you try to force this. That is why we define the symbol automatically inside the msbuild scripts.
Users of the Code Contract tools should never manually try to define or undefine the CONTRACTS_FULL symbol as it is a tool controlled variable.
I've read that book, and there WAS a contract level that only used Contract.Requires. It was the option before none in there, but it's somewhere in that section in the book, definitely.
However, I can't help you with globally undefing CONTRACTS_FULL. Sorry. I think though that in that contract checking level it's automatically undef'd.
EDIT: Yeah, you need to put it at level one (ReleaseRequired).

How can I easily exclude certain lines of code from a compile?

Scattered throughout a software project I am working on are many lines of code that were written for debugging and utility purposes. Before I compile my code, I want a way to select whether or not these blocks of code should be included into my compile (something that won't require navigating the code commenting out). How can I do this?
I'm programming in c# and using Microsoft Visual Studio 2010.
Add the attribute [Conditional("DEBUG")] onto methods you only want to have execute in your debug build. See here for more detailed information.
I would suggest enclosing your blocks in #ifdef SOMETHING and #endif, and then defining SOMETHING in your project settings when you want to include that block in your compile.
You need preprocessor directives, or conditional compile statements. You can read about them here.
An example from that link:
#define TEST
using System;
public class MyClass
{
public static void Main()
{
#if (TEST)
Console.WriteLine("TEST is defined");
#else
Console.WriteLine("TEST is not defined");
#endif
}
}
The code is only compiled if TEST is defined at the top of the code. A lot of developers use #define DEBUG so they can enable debugging code and remove it again just by altering that one line at the top.
Consider using the Debug class to conditionally log, assert, etc. There are many advantages to this. You can choose to log (or not) at runtime. They limit you to (mostly) non-behavior-changing actions, addressing some of #STW's (valid) concern. They allow the use of third-party logging tools.
If they are for debugging, then the only acceptable solution is to surround such code with:
#ifdef DEBUG
#endif
This ensures that the code is included when you compile in debug mode but excluded in release mode.
You can use preprocessor directives w/ #if
You may want to consider moving these debugging functions out of the classes entirely--having your classes "change shape" between Debug and Release mode can be a real headache and can be difficult to diagnose problems.
You could consider creating a seperate "Debug" assembly which contains all your debugging helpers--then just make sure you can exclude it from the solution and build successfully without it.

How do WPF Markup Extensions raise compile errors?

Certain markup extensions raise compile errors. For example StaticExtension (x:Static) raises a compile error if the referenced class cannot be found. Anyone know the mechanism for this? Is it baked into the XAML compiler or is such functionaility available to custom markup extensions?
EDIT: mfeingold below suggested that I need to look into the IVsErrorList interface, but I can't immediately see how that would help someone white a markup extension that generates a compile-time error. Any examples?
Extending the BAML compile process to log additional errors
I encountered this same problem last year. I was writing my own extension for which I wanted compile-time errors in certain scenrios and discovered that just throwing an exception from ProvideValue didn't work because ProvideValue isn't called until the XAML is actually loaded and the object tree is created.
I did some experiments and discovered that the compiler error message for x:Static is a byproduct of an optimization done by the the BAML compiler. The BAML format actually has a concept of a specific member of a specific type, so when the XAML contains x:Static the compiler actually replaces it with a special record that directly references the member rather than containing the type and method name. It does this by explictly recognizing the StaticExtension class. TypeExtension has a similar optimization.
I searched for hooks that would allow me to have my own code called during BAML compilation, but I didn't find any. BAML compilation is mostly just a straight transliteration into a binary format that corresponds to the XAML, with a few specific optimizations but mostly ignoring what it sees.
I ended up adding an extra step to the build process, modeling my code off of Microsoft.WinFX.targets and the other built-in targets files. This step scans the XAML for my markup extension, checks the parameters, and generates a compile error if they are not correct. This is done completely independently of the translation into BAML. It was a couple days' extra work to implement this when all was said and done, but I learned a lot.
Caveat about creating your own .targets file
If you're thinking about adding your own .targets file, you should be aware that unless you include the target in the local machine's SafeImports registry key, both Visual Studio and Expression Blend will complain that about any project that includes your .targets file. This key requires Administrator access on the machine to update. This may or may not be an issue depending on your deployment scenario. (For example, a machine-wide MSI install would fix it, or you could manually set the key if you only have a few development machines). In my case it didn't matter since I already needed the custom .targets file for some other things I was doing in that project.
Error logging from a build task
You don't need IVsErrorList to add errors to Visual Studio during a build (and if you did, you would not properly support command-line builds, Expression Blend, and other tools).
All you need to do is to call Log.LogErrror Log.LogWarning from inside your build task, like this:
public class CheckForErrorsInMyMarkupExtension : Task
{
... parameters here ...
public override Execute()
{
... code to load XAML and scan it for markup extension errors ...
... when you discover an error ...
Log.LogError("I saw an error");
}
}
There are several VisualStudio integration API which allows you to generate your own diagnostic messages from a MEF extension (VS2010 only) a VSIntegration Package or an add-in.
check out IVsErrorList interface as well as OutputTaskItemString method of the IVsOutputWindowPane interface. The latter is what I used in my django editor.
The calls to these methods of course are baked into XAML compiler - how could they not be, they are based on results of the XAML parsing

Categories