Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

Static Analysis Rules - Sooner rather than later

I posted the other day that I wanted to create some static analysis rules for Visual Studio. I have some great ideas for several rules that I want to write in order to do two things. Firstly, I want rules to pick up common mistakes made in coding. Secondly, the rules can be used to enforce coding standards via the Code Analysis TFS checkin policy.

To enforce coding standards, I have previously written xpath and regex TFS checkin policy implementations that work off a set of defined rules. I found that the xpath policy worked really well for files like csproj and sln files. The xml in these files is reasonably simple and the xpath queries are able to easily identify data that is missing or data that shouldn’t be included. I found it was a different story with the regex policy though. It became very difficult to be able to satisfy coding standards using regex on code files. It also only allowed for analysis of content within a single file, not what outside code calls into that file or other files that the code calls out to.

Enter the static analysis rules. It turned out that these are really easy to write. In about an hour, I have created four static analysis rules and tested them. The rules so far are:

Read More

WCF, SSL and localhost

We encountered an interesting issue at work over the last week. We are writing WCF services and implementing transport security to communicate with IIS. For local development, we had certificates created by a certificate server and configured onto the local IIS. As you would expect, the certificates used the machine name for the common name of the certificate. This is after all the standard procedure.

The problem encountered is that the web application project in Visual Studio stores the url of the project in the csproj file rather than the user settings file. This is the url of the application that Visual Studio will attach to in order to debug in IIS. The url has to be a reference to the local machine. As the project is under source control, the url stored as a project setting is now put onto the machines of other developers. So if I configure the project to point to my machine using https, check in the file and another developer gets it, then their version of the project now points to my machine rather than theirs. Bit of a problem.

There were two ideas that we quickly came up with:

Read More

Writing your own FxCop rules

Jason Kresowaty has posted an incredible amount of information about creating FxCop rules. I’ll get to these one day. One rule I want to write is a rule that checks for properties on a DataContract that are not assigned the DataMember attribute.

Read More

Scope Sneak

I came up with a new term today - scope sneak.

Sneak [sneek]: verb, sneaked or snuck, sneak·ing, noun

–verb (used without object)

  1. to go in a stealthy or furtive manner; slink; skulk.
  2. to act in a furtive or underhand way.
  3. British Informal. to tattle; inform.

Something happened at work today when a friend highlighted that some requirements had been snuck into a requirements document he was developing from. It occurred to me that this isn’t really scope creep (also seen here). Scope creep to me implies that everyone on the project knows that requirements are being added or changed (usually expanded). This situation was a bit more like requirements were added on the sly, hence scope sneak.

Read More

Incorrect code coverage references in testrunconfig

I have been having a problem with testrunconfig files recently.

Lets say I have developed a project with which I also have a unit test project in the solution. I have done this using the Debug build configuration. I set up the code coverage and everything is fine. I then make some changes to the code and also happen to change the build configuration. If I rerun the unit tests, Visual Studio starts freaking out.

When you select an assembly for code coverage, a relative path to that assembly is stored in the testrunconfig file. The issue is that the relative is specific to a build configuration. In this case, the testrunconfig points code coverage to the assemblies in bin\Debug rather than the path related to my current build configuration. But I have changed the code so that the assemblies in bin\Debug are out of date and don’t match the code being executed by the unit test under the current build configuration.

After talking to Microsoft about it, their workaround was to replace bin\Debug with the %OutDir% macro in the relative paths in the testrunconfig file. This macro gets evaluated and the correct build configuration path gets added into the path when the assembly path is resolved. This is not supported in the IDE so you will have to open the testrunconfig using the xml editor and modify the relative path by hand.

Read More

LogLevel NAnt Task

An ongoing issue that I am having with NAnt scripts is bloat in the log records being written to the screen and to disk. Tasks like xmlpeek and regex log messages that I am not interested in for the given logging threshold. It would be nice to not have these unwanted messages logged but for everything else to be logged as expected given the defined log threshold.

After doing some searching, I came across this post from Jay Flowers. Will Buttitta posted another version of the same idea in a comment against that post. Using tasks to change the logging threshold at runtime for a particular part of the script is a great idea. Unfortunately, I have found that neither of these implementations work.

After going through Reflector, I have found that classes that are derived from Task and call the Log method end up invoking Element.Log() which calls straight down to Project.Log(). The Project.Log method does not check the logging threshold before writing the log entry. What I haven’t been able to figure out is why Task.Log is not invoked. If it was, then I think the two solutions in Jay’s post would probably work as Task.Log() checks the current logging threshold before calling down to the base class.

Read More

Bug found in calculating Code Metrics in VS2008

I have found that several of my VS2008 solutions are not able to calculate code metrics for a couple of their projects. The error message returned is:

An error occurred while calculating code metrics for target file ‘<File path>’ in project <ProjectA>. The following error was encountered while reading module ‘<ProjectB>’: Could not resolve type reference: [mscorlib].

After consulting David Kean and Todd King at Microsoft (FxCop team), they have found the issue. Todd’s response was:

It looks like we have a bug in metrics where if one of your project’s reference assemblies uses an attribute that lives in an assembly that is not one of your project’s other reference assemblies metrics will fail because when it goes to try to populate all the attributes on your reference assemblies because it won’t be able to find the type information for that attribute. We are tracking this bug and should have it fixed in SP1. For now the workaround is to add a few extra references to some of your projects.

I found this issue when developing WCF services. The problem scenario was because of WCF attributes in a service contract assembly being referenced by a service host where the service host didn’t reference System.ServiceModel. The service host compiles, but failed to have code metrics calculated for it. A simplified repro example is ProjectA references ProjectB which references AssemblyC. ProjectA fails to calculate code metrics because it doesn’t reference AssemblyC.

There is a second bug here as well. The error message points to mscorlib as the type reference that couldn’t be resolved. This is not correct and is misleading.

Todd has said that this bug will be fixed in SP1. Until then, the workaround is to look at the references in ProjectB that are not in ProjectA. Gradually add the missing references until code metrics can be calculated.

Read More

Locking/Thread Synchronization Performance Question

Here is my scenario:

I have a static method which checks some static generic dictionaries to determine whether keys exist. If keys don’t exist, they will get added along with a value.

Rough "metrics" will be:

  • the static method will get called a lot
  • items will rarely get added to the dictionary
  • items are never removed from the dictionary
  • the dictionary will only contain a few items
  • as many times as the method is called, the dictionary will be referenced using the ContainsKey property (and the indexer property where ContainsKey == true)

In order to ensure thread safety of adding a new item to the dictionary, a lock is required. Two options I see are as follows:

Read More

VS2008 read-only automatic properties

I have started using the very nice automatic properties in VS2008. As I was using these, I was thinking about how they work when you define the property as read-only or write-only. Without a backing field, you wouldn’t be able to read from or write to the backing field, rendering the property useless.

I coded an automatic property in this way and didn’t get any error indication from the IDE, but I didn’t actually compile it. I have since run some code analysis that suggests that my collection properties should be readonly. As these properties are automatic properties, I then removed the setter and compiled.

Boom! Now there is a compiler error CS0840 that includes the message "Automatically implemented properties must define both get and set accessors". It is unfortunate that this wasn’t indicated with those helpful squiggly red lines in the code editor, but not a major problem.

Read More