Using Code Analysis with Silverlight
Ever since I was in the C++ world, I have been enamored with code analysis tools; I used to live by PC-Lint. So since I started using C# a few years ago code analysis was something that I wanted to integrate into my C# coding practice as well. The first tool that I started using was FxCop, a tool that analyzes managed code assemblies and produces similar useful results. Since I have been doing lots of Silverlight work lately, I was excited to see that FxCop is now part of Visual Studio 2008 - in the project's Code Analysis Tab. By checking the Enable Code Analysis box in this setting page, code analysis is then added to the build process and runs after the assembly compiles successfully.
Since Silverlight development is somewhat different from standard .Net development, I've had to modify my projects to take advantage of code analysis but not be warned about "false positives" - warnings that should be ignored. I typically do three things in my Silverlight projects for code analysis:
- Disable a few rules that are unnecessary for Silverlight development
- Add a few assembly attributes to my code
- Add a CodeAnalysisDictionary.xml to my project
- Fix issues flagged by Code Analysis
Disable Code Analysis Rules
I disable these rules in the project's Code Analysis tab:
- Design Rule CA2210: Assemblies should have valid strong names. Because I don't build production code - only samples, during development I don't sign my assemblies
- Performance Rule CA1811: Avoid uncalled private code. Event handlers that are declared in XAML will trigger this
- Performance Rule CA1823: Avoid unused private fields. Visual Studio creates fields for all XAML elements with x:Name attributes.
Add Assembly Attributes
In the Properties/AssemblyInfo.cs I add two assembly attributes.
using System;
using System.Resources;
[assembly: CLSCompliant(false)]
[assembly: NeutralResourcesLanguage("en-US")]
Since System.Windows.DependecyObject is not CLS compliant, most Silverlight assemblies will not be either. This is not a problem because Silverlight operates in its own secure sandbox and does not interoperate with other .Net assemblies. I added the NeutralResourcesLanguage attribute because of rule CA1824.
Add a Code Analysis Dictionary to the Project
Typically in a project you will have proper nouns and cool-looking acronyms (like PiP or VoD). Since code analysis actually uses a dictionary to check the spelling of words, those terms are not found. What I like to do is add a code analysis dictionary to my project and set the Build Action to CodeAnalysisDictionary. The dictionary is just an XML file with the CodeAnalysisDictionary build action:
Then in the dictionary, I can add my words, deprecated terms, and cool-looking acronyms:
<?xml version="1.0" encoding="utf-8" ?>
<Dictionary>
<Words>
<Unrecognized>
<Word>Unrecog</Word>
</Unrecognized>
<Recognized>
<Word>Scherotter</Word>
<Word>Mindjet</Word>
<Word>mmap</Word>
</Recognized>
<Deprecated>
<Term PreferredAlternate="Best">Bestest</Term>
<Term PreferredAlternate="Better">Gooder</Term>
</Deprecated>
</Words>
<Acronyms>
<CasingExceptions>
<Acronym>PiP</Acronym>
<Acronym>VoD</Acronym>
</CasingExceptions>
</Acronyms>
</Dictionary>
Interestingly I could not find a XSD Schema describing this format either in Visual Studio or online. If you have the schema, then Visual Studio's intellisense helps you keep the syntax correct. One helpful thing that you can do with Visual Studio is have Visual Studio create a schema for you based on an XML file:
This creates the XSD file for you. Once you have created the XSD file, copy it to C:\Program Files (x86)\Microsoft Visual Studio 9.0\Xml\Schemas so that it can be easily used by the XML editor in Visual Studio. I have uploaded my version to the MSDN code gallery to give help you. If you want to use it:
Download it from https://code.msdn.microsoft.com/CADictionaryXSD
Copy it to C:\Program Files (x86)\Microsoft Visual Studio 9.0\Xml\Schemas
Select the code analysis dictionary file in your solution explorer,
In the properties window click on the schemas property, click on the browse button
Check the Use column for the CodeAnalysisDictionary.xsd file listed in the XML Schemas dialog:
You will then have intellisense for the Code Analysis dictionary that you are creating.
Fix Issues Flagged by Code Analysis
Now that it's all configured you should start using Code Analysis to make sure your code is clean and conformant. There is one false positive that I don't disable. If you create your own exception class, you will see CA1032 if you don't create the standard constructors (one warning for each missing constructor). If you try to fix these, you will find that CA1032 cannot be fixed for one of the constructors:
MSBUILD : warning : CA1032 : Microsoft.Design : Add the following constructor to 'MindMapException': protected MindMapException(SerializationInfo, StreamingContext).
Since SerializationInfo and StreamingContext are not implemented in Silverlight, there is no way to fix this issue. Since the other CA1032 issues are valid, I keep this warning enabled - I can live with one type of false positive but I document it in the source code class remarks:
/// <summary>
/// MindMap Exception
/// </summary>
/// <remarks>Ignore Code Analysis warning CA1032 for protected MindMapException(SerializationInfo, StreamingContext)</remarks>
public class MindMapException : Exception
{
...
}
I hope this helps you write better Silverlight code now.
Comments
Anonymous
August 05, 2008
PingBack from http://blog.kantikalyan.com/links-august-5th-2008/Anonymous
August 10, 2008
Michael Washington with an add-on for SL Desktop already, Mike Snow beginning Terrain tutorials and applyingAnonymous
August 12, 2008
After fixing all that can be fixed in terms of exception constructors, wouldn't a [SuppressMessage] attribute with an appropriate Justification= be the cleaner way to go? (Short of writing stub classes to fake the serialization constructor, that is.)Anonymous
August 28, 2008
I think the Schema for the code analysis dictionary has inapropriate lower bounds for most elements. I believe each of the Words, Unrecognized, Recognized, Deprecated, and Acronyms elements should have minOccurs="0". At the moment a custom dictionary without at least one Unrecognized word is considered to violate the schema. Regards,Anonymous
August 29, 2008
Jason, Thanks for the suggestion. I updated the schema file on the MSDN Code gallery. Michael