<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David DeWinter &#187; MSBuild</title>
	<atom:link href="http://davedewinter.com/category/msbuild/feed/" rel="self" type="application/rss+xml" />
	<link>http://davedewinter.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Tue, 09 Aug 2011 21:05:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Generate Serialization Classes As Part of Your Build (Part 2)</title>
		<link>http://davedewinter.com/2008/09/28/generate-serialization-classes-as-part-of-your-build-part-2/</link>
		<comments>http://davedewinter.com/2008/09/28/generate-serialization-classes-as-part-of-your-build-part-2/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 19:12:51 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[Code Generation]]></category>
		<category><![CDATA[Object Model]]></category>
		<category><![CDATA[Serialization]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[xsd.exe]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/2008/09/28/generate-serialization-classes-as-part-of-your-build-part-2/</guid>
		<description><![CDATA[A while ago, I posted about integrating the xsd.exe tool into the build process within Visual Studio or MSBuild. This time around, we&#8217;ll look at generating the code for the XML Serialization object model and making a few tweaks as &#8230; <a href="http://davedewinter.com/2008/09/28/generate-serialization-classes-as-part-of-your-build-part-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.rev-net.com/ddewinter/2008/07/08/generate-serialization-classes-as-part-of-your-build-part-1/">A while ago</a>, I posted about integrating the xsd.exe tool into the build process within Visual Studio or MSBuild. This time around, we&#8217;ll look at generating the code for the XML Serialization object model and making a few tweaks as part of the process. Here I will specifically look at retrieving the comments in the xsd:documentation elements and applying them to code elements as XML comments. We&#8217;ll break this down into four key steps along with some closing comments and source code.</p>
<p> <span id="more-123"></span>
<ul>
<li><a href="#creating-the-schema">Creating the Schema</a> </li>
<li><a href="#generating-the-code">Generating the Code</a> </li>
<li><a href="#making-your-modifications">Making Your Modifications (xs:documentation comments to XML comments)</a> </li>
<li><a href="#integrating-with-msbuild">Integrating with MSBuild</a> </li>
<li><a href="#let-the-buyer-beware">Let the Buyer Beware</a> </li>
<li><a href="#source-code">Reference Source Code</a> </li>
</ul>
<h3 id="creating-the-schema">Creating the Schema</h3>
<p>Before we start, we&#8217;ll need a schema to work with. For simplicity, we&#8217;ll use the same schema as last time with the addition of xsd:documentation elements to provide descriptions for some elements and attributes. The complex types are also no longer anonymous.</p>
<div class="cf">
<p style="margin: 0px"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml</span><span style="color: blue"> </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot;<span style="color: blue"> </span><span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue">?&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">xs:schema</span><span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">targetNamespace</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.example.com/SampleSchema.xsd</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">elementFormDefault</span><span style="color: blue">=</span>&quot;<span style="color: blue">qualified</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">xmlns</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.example.com/SampleSchema.xsd</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">xmlns:xs</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://www.w3.org/2001/XMLSchema</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">xs:element</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">root</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">rootType</span>&quot;<span style="color: blue">/&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">xs:complexType</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">rootType</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:sequence</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:element</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">first</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">firstType</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:element</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">second</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">secondType</span>&quot;<span style="color: blue">/&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:sequence</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">xs:complexType</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">firstType</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:annotation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:documentation</span><span style="color: blue">&gt;</span>Describes the first element in the document.<span style="color: blue">&lt;/</span><span style="color: #a31515">xs:documentation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:annotation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:attribute</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">name</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">xs:token</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:annotation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:documentation</span><span style="color: blue">&gt;</span>The name of the first element.<span style="color: blue">&lt;/</span><span style="color: #a31515">xs:documentation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:annotation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:attribute</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:attribute</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">value</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">xs:token</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:annotation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:documentation</span><span style="color: blue">&gt;</span>The value of the first element.<span style="color: blue">&lt;/</span><span style="color: #a31515">xs:documentation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:annotation</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:attribute</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">xs:complexType</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">secondType</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:attribute</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">origin</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">xs:token</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">xs:schema</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>The descriptions here are nonsensical, but this example is small enough to demonstrate the power of what we can do with custom code generation. We still aim to generate classes at build time, but first we have to implement the logic that the build step will use. The next sections describe what we need to do.</p>
<h3 id="generating-the-code">Generating the Code</h3>
<p>The first step is to import the schema into the code.</p>
<div class="cf"><span style="color: #2b91af">XmlSchemas</span> schemaSet = <span style="color: blue">new</span> <span style="color: #2b91af">XmlSchemas</span>();</div>
<div class="cf"><span style="color: #2b91af">XmlSchema</span> xsd = <span style="color: blue">null</span>;</div>
<p class="cf" style="margin: 0px"><span style="color: blue">using</span> (<span style="color: #2b91af">XmlReader</span> reader = <span style="color: #2b91af">XmlReader</span>.Create(mySourceXsdFile))</p>
<p class="cf" style="margin: 0px">{</p>
<p class="cf" style="margin: 0px">&#160;&#160;&#160; xsd = <span style="color: #2b91af">XmlSchema</span>.Read(reader, <span style="color: blue">null</span>);</p>
<p class="cf" style="margin: 0px">&#160;&#160;&#160; schemaSet.Add(xsd);</p>
<p class="cf" style="margin: 0px">}</p>
<p>We instantiate a new instance of the <span class="cf">System.Xml.Serialization.<span class="cb2">XmlSchemas</span></span> (in System.Xml.dll) class and add the schema file to that schema set. In the code above, <span class="cf">mySourceXsdFile</span> is a field which is set during the construction of the object which contains this code. The next step is to translate the schema definition into a CodeDom <span class="cf"><span class="cb2">CodeNamespace </span></span>and then export that <span class="cf"><span class="cb2">CodeNamespace </span></span>instance to code. Simple, right?</p>
<p>Fortunately for us, there are classes built into the framework to handle this. First we set up a schema importer and a code exporter:</p>
<div class="cf">
<p style="margin: 0px"><span style="color: green">// Load the XSD into the importer</span></p>
<p style="margin: 0px"><span style="color: #2b91af">XmlSchemaImporter</span> importer = <span style="color: blue">new</span> <span style="color: #2b91af">XmlSchemaImporter</span>(schemaSet);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: green">// Set up the objects needed for code export.</span></p>
<p style="margin: 0px"><span style="color: #2b91af">CodeNamespace</span> ns = <span style="color: blue">new</span> <span style="color: #2b91af">CodeNamespace</span>(<span style="color: blue">this</span>.Namespace);</p>
<p style="margin: 0px"><span style="color: #2b91af">XmlCodeExporter</span> exporter = <span style="color: blue">new</span> <span style="color: #2b91af">XmlCodeExporter</span>(ns);</p>
</p></div>
<p>The argument for the <span class="cf"><span class="cb2">CodeNamespace</span></span> constructor takes a string representing the desired namespace name for the generated code. The translation between these objects occurs using an <span class="cf">System.Xml.Serialization.<span class="cb2">XmlTypeMapping</span></span> instance to connect the two. To create the type mapping, we&#8217;ll need an <span class="cf">System.Xml.<span class="cb2">XmlQualifiedName</span></span> representing the root element of the schema. The exporter can then export that type mapping to a CodeDom representation, which we can utilize to write the code output to a file. The result looks something like this:</p>
<div class="cf">
<p style="margin: 0px"><span style="color: #2b91af">XmlSchemaObjectCollection</span> xsdObjects = xsd.Items;</p>
<p style="margin: 0px"><span style="color: blue">int</span> xsdObjectCount = xsdObjects.Count;</p>
<p style="margin: 0px"><span style="color: blue">for</span> (<span style="color: blue">int</span> i = 0; i &lt; xsdObjectCount; ++i)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaObject</span> xsdObject = xsdObjects[i];</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaElement</span> xsdElement = xsdObject <span style="color: blue">as</span> <span style="color: #2b91af">XmlSchemaElement</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">if</span> (xsdElement != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Import the mapping</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XmlTypeMapping</span> mapping = importer.ImportTypeMapping(</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XmlQualifiedName</span>(xsdElement.Name, xsd.TargetNamespace)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; );</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; exporter.ExportTypeMapping(mapping);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">break</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: green">// Build code generator</span></p>
<p style="margin: 0px"><span style="color: #2b91af">CSharpCodeProvider</span> codeProvider = <span style="color: blue">new</span> <span style="color: #2b91af">CSharpCodeProvider</span>();</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: blue">using</span> (<span style="color: #2b91af">StreamWriter</span> sw = <span style="color: blue">new</span> <span style="color: #2b91af">StreamWriter</span>(<span style="color: #a31515">&quot;OutputFile.cs&quot;</span>))</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; codeProvider.GenerateCodeFromNamespace(ns, sw, <span style="color: blue">new</span> <span style="color: #2b91af">CodeGeneratorOptions</span>());</p>
<p style="margin: 0px">}</p>
</p></div>
<p>The code above iterates over items in the schema until the root element (<span class="cf"><span class="cb2">XmlSchemaElement</span></span>) is found, at which the importer will import the type mapping, and the exporter will export it to the <span class="cf"><span class="cb2">CodeNamespace </span></span>defined earlier. At the end of the for loop, the CodeNamespace object contains all of the types representing the XML schema. At the end, we tell a <span class="cf"><span class="cb2">CSharpCodeProvider </span></span>to generate code from the types in the namespace to an output file, ready for consumption. The code is very simple; however, we are not utilizing the CodeDom APIs to their full potential. Because the types are accessible before generating the code, we can make <em>any changes we desire</em> before writing the code. This is the crux of this post&#8212;being able to customize the generated code.</p>
<h3 id="making-your-modifications">Making Your Modifications</h3>
<p>If you are familiar with the CodeDom APIs, then at this point you can probably start making your own modifications. But, just in case you aren&#8217;t, I will quickly walk through how to generate XML documentation comments on the generated code members. Re-examining the loop over the objects in the XML schema, we can reasonably infer <em>based on our specific schema</em> that there is more than one object in the collection. In this case, the other named complex types are part of this collection; consequently, we can modify the code in the loop to consider elements and attributes:</p>
<div class="cf">
<p style="margin: 0px"><span style="color: green">// Cached copy of the types as IEnumerable&lt;T&gt; to use LINQ queries on.</span></p>
<p style="margin: 0px"><span style="color: #2b91af">IEnumerable</span>&lt;<span style="color: #2b91af">CodeTypeDeclaration</span>&gt; codeTypes = <span style="color: blue">null</span>;</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: #2b91af">XmlSchemaObjectCollection</span> xsdObjects = xsd.Items;</p>
<p style="margin: 0px"><span style="color: blue">int</span> xsdObjectCount = xsdObjects.Count;</p>
<p style="margin: 0px"><span style="color: blue">for</span> (<span style="color: blue">int</span> i = 0; i &lt; xsdObjectCount; ++i)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaObject</span> xsdObject = xsdObjects[i];</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaElement</span> xsdElement = xsdObject <span style="color: blue">as</span> <span style="color: #2b91af">XmlSchemaElement</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">if</span> (xsdElement != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Import the mapping</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XmlTypeMapping</span> mapping = importer.ImportTypeMapping(</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XmlQualifiedName</span>(xsdElement.Name, xsd.TargetNamespace)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; );</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; exporter.ExportTypeMapping(mapping);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; codeTypes = ns.Types.Cast&lt;<span style="color: #2b91af">CodeTypeDeclaration</span>&gt;();</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">continue</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaComplexType</span> xsdComplexType = xsdObject <span style="color: blue">as</span> <span style="color: #2b91af">XmlSchemaComplexType</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">if</span> (xsdComplexType != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">string</span> complexTypeName = xsdComplexType.Name;</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// We should throw (with First) if we can&#8217;t find a type with this complex type&#8217;s name.</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">CodeTypeDeclaration</span> codeTypeDeclaration = </p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; codeTypes.First(ct =&gt; ct.Name == complexTypeName);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Get documentation specifically for the complex type.</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">string</span> documentation = GetDocumentation(xsdComplexType);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; SetSummaryComment(codeTypeDeclaration, documentation);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Now get documentation for the attributes</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaObjectCollection</span> attributes = xsdComplexType.Attributes;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">int</span> attributeCount = attributes.Count;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">for</span> (<span style="color: blue">int</span> j = 0; j &lt; attributeCount; ++j)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaAttribute</span> xsdAttribute = (<span style="color: #2b91af">XmlSchemaAttribute</span>)attributes[j];</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">string</span> attributeName = xsdAttribute.Name;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">CodeMemberProperty</span> property = codeTypeDeclaration.Members.OfType&lt;<span style="color: #2b91af">CodeMemberProperty</span>&gt;().First(</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; prop =&gt; prop.Name == attributeName);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">string</span> attributeDocumentation = GetDocumentation(xsdAttribute);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SetSummaryComment(property, attributeDocumentation);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">}</p>
</p></div>
<p>There are a few significant changes here. First, immediately after the type mapping is exported, we cast all of the <span class="cf"><span class="cb2">CodeNamespace</span></span>&#8216;s types to <span class="cf cb2">CodeTypeDeclaration</span>s for use later in the loop. On subsequent iterations of the loop, we anticipate running into <span class="cf"><span class="cb2">XmlSchemaComplexType</span></span> objects. The code then retrieves the appropriate <span class="cf cb2">CodeTypeDeclaration</span> which matches that complex type, retrieves the documentation for that type, and sets the summary comment. The pattern is repeated for the attributes in each complex type.</p>
<p>The <span class="cf">GetDocumentation</span> and <span class="cf">SetSummaryComment</span> methods are fairly simple and involve manipulating the object models of XML Schema and CodeDom, respectively, to achieve their goals. Fortunately for the <span class="cf">GetDocumentation</span> method, there is a base class in the object model which encapsulates all elements which can be annotated.</p>
<div class="cf">
<p style="margin: 0px"><span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">string</span> GetDocumentation(<span style="color: #2b91af">XmlSchemaAnnotated</span> annotatedElement)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: green">// Look inside the Annotation element</span></p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaAnnotation</span> annotation = annotatedElement.Annotation;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">if</span> (annotation != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaObjectCollection</span> annotationItems = annotation.Items;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (annotationItems.Count &gt; 0)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XmlSchemaDocumentation</span> xsdDocumentation =</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; annotationItems[0] <span style="color: blue">as</span> <span style="color: #2b91af">XmlSchemaDocumentation</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (xsdDocumentation != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XmlNode</span>[] markup = xsdDocumentation.Markup;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (markup.Length &gt; 0)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span> markup[0].InnerText;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">return</span> <span style="color: #2b91af">String</span>.Empty;</p>
<p style="margin: 0px">}</p>
</p></div>
<p>Above we assume that the xsd:documentation element will be the first one within the xsd:annotation element. <strong>This is not a safe assumption for all schemas.</strong></p>
<div class="cf">
<p style="margin: 0px"><span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">void</span> SetSummaryComment(<span style="color: #2b91af">CodeTypeMember</span> codeTypeMember, <span style="color: blue">string</span> comment)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">if</span> (comment == <span style="color: blue">null</span> || <span style="color: #2b91af">String</span>.Empty.Equals(comment, <span style="color: #2b91af">StringComparison</span>.Ordinal))</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">CodeCommentStatementCollection</span> comments = codeTypeMember.Comments;</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">if</span> (comments.Count == 0)</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; comments.Add(<span style="color: blue">new</span> <span style="color: #2b91af">CodeCommentStatement</span>(<span style="color: #2b91af">String</span>.Empty, <span style="color: blue">true</span>));</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; comments[0].Comment.Text = <span style="color: #2b91af">String</span>.Format(</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515">&quot;&lt;summary&gt;{0} {1}{0} &lt;/summary&gt;&quot;</span>,</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">Environment</span>.NewLine,</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; comment);</p>
<p style="margin: 0px">}</p>
</p></div>
<h3 id="integrating-with-msbuild">Integrating with MSBuild</h3>
<p>The final step is to integrate this code generator with MSBuild. If you are familiar with creating custom tasks in MSBuild, then this will be review for you. However, the steps are as follows:</p>
<ol>
<li>(Optional) Encapsulate the business logic laid out above into a separate, re-usable class. </li>
<li>Create a class inheriting from <span class="cf">Microsoft.Build.Utilities.<span class="cb2">Task</span></span> (in Microsoft.Build.Utilities.dll or Microsoft.Build.Utilities.v3.5.dll). </li>
<li>Create properties for each parameter that the task uses to accomplish its goal. (You may consider items like XsdFileLocation or DestinationFile.) </li>
<li>Override the Execute method to carry out your custom logic, utilizing the properties as necessary. </li>
</ol>
<p>A sample implementation could look like this:</p>
<div class="cf">
<p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">XsdGen</span> : <span style="color: #2b91af">Task</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">string</span> DestinationFile</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">get</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">set</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; [<span style="color: #2b91af">Required</span>]</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">string</span> Namespace</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">get</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">set</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; [<span style="color: #2b91af">Required</span>]</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">string</span> XsdLocation</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">get</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">set</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: blue">bool</span> Execute()</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">try</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">XsdCodeGenerator</span> generator = <span style="color: blue">new</span> <span style="color: #2b91af">XsdCodeGenerator</span>(XsdLocation, Namespace);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; generator.DestinationFile = DestinationFile;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; generator.Generate();</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span> <span style="color: blue">true</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Log.LogErrorFromException(ex, <span style="color: blue">false</span>);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span> <span style="color: blue">false</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">}</p>
</p></div>
<p>Once the task is created, we can go back to editing the project file as we did in the <a href="http://blogs.rev-net.com/ddewinter/2008/07/08/generate-serialization-classes-as-part-of-your-build-part-1/">first post in the series</a>. As a reminder, here is what we had before:</p>
<div class="cf">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue"> </span><span style="color: red">Inputs</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.xsd</span>&quot;<span style="color: blue"> </span><span style="color: red">Outputs</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.cs</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Exec</span><span style="color: blue"> </span><span style="color: red">Command</span><span style="color: blue">=</span>&quot;<span style="color: red">&amp;quot;</span><span style="color: blue">C:Program FilesMicrosoft SDKsWindowsv6.0Binxsd.exe</span><span style="color: red">&amp;quot;</span><span style="color: blue"> SampleSchema.xsd /classes</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">BeforeBuild</span>&quot;<span style="color: blue"> </span><span style="color: red">DependsOnTargets</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>And here is what we have now:</p>
<div class="cf"><span style="color: blue">&lt;</span><span style="color: #a31515">UsingTask</span><span style="color: blue"> </span><span style="color: red">AssemblyFile</span><span style="color: blue">=</span>&quot;<span style="color: blue">DeWinter.XsdGen.dll</span>&quot;<span style="color: blue"> </span><span style="color: red">TaskName</span><span style="color: blue">=</span>&quot;<span style="color: blue">XsdGen</span>&quot;<span style="color: blue"> /&gt;</span></div>
<div class="cf"><span style="color: blue"></span><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue"> </span><span style="color: red">Inputs</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.xsd</span>&quot;<span style="color: blue"> </span><span style="color: red">Outputs</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.g.cs</span>&quot;<span style="color: blue">&gt;</span></div>
<p class="cf" style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">XsdGen</span><span style="color: blue"> </span><span style="color: red">DestinationFile</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.g.cs</span>&quot;<span style="color: blue"> </span><span style="color: red">Namespace</span><span style="color: blue">=</span>&quot;<span style="color: blue">DeWinter.Samples.Serialization</span>&quot;<span style="color: blue"> </span><span style="color: red">XsdLocation</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.xsd</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p class="cf" style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
<p class="cf" style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">BeforeBuild</span>&quot;<span style="color: blue"> </span><span style="color: red">DependsOnTargets</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue">&gt;</span></p>
<p class="cf" style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
<p>Before the actual compilation step, MSBuild will execute the GenerateSerializationClasses target, locate the XsdGen task in DeWinter.XsdGen.dll, and then call the Execute method on that task. This will generate the XML Schema object model as desired (notice the XML comments below):</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/09/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="316" alt="XML Schema Object Model" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/09/image-thumb.png" width="649" border="0" /></a> </p>
<h3 id="let-the-buyer-beware">Let the Buyer Beware</h3>
<p>The ironic part about writing this post is that the more I wrote, the less appealing this method was. Think about it; you are essentially writing a <em>replacement</em> for xsd.exe. The more generalized you want to make it the more difficult it becomes. In this post I accounted for named complex types only. What about anonymous complex types? Complex types that are extensions or restrictions of other complex types? Other facets like enumerations? XML Schema has a multitude of different elements, and building a suitable replacement for xsd.exe that suits your needs <em>just isn&#8217;t worth it</em> most of the time.</p>
<p>The other problem I have with it is just that there is so little gain to justify the amount of work you would put into it. My original justification for investigating this method was that it made the object model much nicer to work with, because it was well-commented and not as awkward to use as the normally generated OM (object model). But that&#8217;s really subjective!</p>
<p>My personal opinion, though, is that the object model generated by xsd.exe is fine. If you really want an object model that is &quot;better&quot; to work with (whatever &quot;better&quot; means to you), then build an abstraction layer on top of the generated OM and have a service class translate between the two. In my next post on serialization I&#8217;ll cover this.</p>
<h3 id="source-code">Reference Source Code</h3>
<p>This was my reference for this post, and there quite a few more features included, like stripping suffixes from type names and &quot;correcting&quot; the casing of the generated classes. (Hmm, that is becoming a theme among my work now, isn&#8217;t it&#8230;?). But it is not complete and probably works only against very limited situations. I would advise you to use this for reference only. And of course, the disclaimer&#8230;</p>
<p><strong style="color: red">Disclaimer</strong>: This software is provided as is, and I am not responsible or liable for any damages arising in any way out of the use of this software, even if advised of the possibility of such damage.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/09/DeWinter.XsdGen.zip">Download</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/09/28/generate-serialization-classes-as-part-of-your-build-part-2/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Generate Serialization Classes As Part of Your Build (Part 1)</title>
		<link>http://davedewinter.com/2008/07/08/generate-serialization-classes-as-part-of-your-build-part-1/</link>
		<comments>http://davedewinter.com/2008/07/08/generate-serialization-classes-as-part-of-your-build-part-1/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 12:58:56 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Automating]]></category>
		<category><![CDATA[Serialization]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[xsd.exe]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/2008/07/08/generate-serialization-classes-as-part-of-your-build-part-1/</guid>
		<description><![CDATA[Yes, I am back from the grave. The past two months have been infuriatingly busy for me (and you&#8217;ll see why in a later post), but I finally have some time to write again. The topic? Generating serialization classes as &#8230; <a href="http://davedewinter.com/2008/07/08/generate-serialization-classes-as-part-of-your-build-part-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Yes, I <em>am</em> back from the grave. The past two months have been infuriatingly busy for me (and you&#8217;ll see why in a later post), but I finally have some time to write again. The topic? Generating serialization classes <em>as part of your build process </em>(Part 1) and <em>in your own way </em>(Part 2).</p>
<p>I might reach only a niche of .NET developers with this post, but it&#8217;s something that niche should be aware of. There is a tool in the .NET framework called <a href="http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx">xsd.exe</a>, and one of its functions is to generate code, specifically .NET classes, from an XML Schema file (XSD). The tool decorates these classes with XML serialization attributes such that when .NET serializes an instance of the generated class that represents the root element, the output conforms to that XML schema. Often, developers using XML schemas will need to change them throughout the course of a project. Leveraging xsd.exe in a project thus requires the generated classes to be updated when an XML schema is updated. This is a bit dangerous in larger projects because not all developers may realize that the tool must be re-run, especially in the case of extremely minor changes to the schema.</p>
<p>Wouldn&#8217;t it be better to have a tighter integration among the XML schema, the generated classes, and the build environment? Fortunately, we can achieve this with a few simple steps, thanks to the MSBuild system for projects inside Visual Studio.</p>
<p><span id="more-105"></span></p>
<p>We&#8217;ll start from scratch here, so first things first: create a new project. Here I&#8217;ll just create a class library called &quot;DeWinterXsd&quot;. Then add a new XML Schema file to the project. (You can find it under the Data category of items.)</p>
<p style="list-style-type: none"><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="486" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image-thumb.png" width="808" border="0" /></a></p>
<p>Replace the contents of the schema file with the following snippet. It&#8217;s a very simple schema, featuring a root element and two child elements with three attributes among them.</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml</span><span style="color: blue"> </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot;<span style="color: blue"> </span><span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue">?&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">xs:schema</span><span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">targetNamespace</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.example.com/SampleSchema.xsd</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">elementFormDefault</span><span style="color: blue">=</span>&quot;<span style="color: blue">qualified</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">xmlns</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.example.com/SampleSchema.xsd</span>&quot;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: red">xmlns:xs</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://www.w3.org/2001/XMLSchema</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">xs:element</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">root</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:sequence</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:element</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">first</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:attribute</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">name</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">xs:token</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:attribute</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">value</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">xs:token</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:element</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:element</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">second</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">xs:attribute</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">origin</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">xs:token</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:element</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:sequence</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">xs:complexType</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">xs:element</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">xs:schema</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>Now that you have the schema, add a new class to your project with the same name as your XML schema file. For example, the name of my schema file is &quot;SampleSchema.xsd&quot;, and the name of the class is &quot;SampleSchema.cs&quot;. This should nest the .cs file underneath the schema file, akin to how code-behind files are nested under UI files (<em>e.g.</em> Windows Forms, XAML). So how do we generate serialization classes? Right click on your project file and select &quot;Unload Project&quot;.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image1.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="519" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image-thumb1.png" width="312" border="0" /></a></p>
<p>And then right click on the project again and click &quot;Edit <em>xxx</em>.csproj&quot;.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image2.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="169" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image-thumb2.png" width="281" border="0" /></a></p>
<p>Now you&#8217;ll see the contents of the .csproj file itself. If you&#8217;re not familiar with the MSBuild system, then here&#8217;s the gist of it. Building a project in your solution executes a series of tasks, which are logically grouped into <em>targets</em>. Building will actually run only one target, <em>Compile</em>. However, the Compile target can depend on other targets in order to run correctly, so those targets are run before Compile, and so on. Take a look at your output window sometime while building; it will show you the tasks being executed by each target. For more information, read an MSBuild tutorial, like <a href="http://www.codeplex.com/msbuildshellex/Wiki/View.aspx?title=MSBuild%20Tutorial&amp;referringTitle=Manual">this one</a>.</p>
<p>What we&#8217;ll do now is say that before the compilation target occurs, we want to generate serialization classes using xsd.exe. Scroll to the bottom of the file and you should see this:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;!&#8211;</span><span style="color: green"> To modify your build process, add your task inside one of the targets below and uncomment it.</span></p>
<p style="margin: 0px"><span style="color: green">Other similar extension points exist, see Microsoft.Common.targets.</span></p>
<p style="margin: 0px"><span style="color: green">&lt;Target Name=&quot;BeforeBuild&quot;&gt;</span></p>
<p style="margin: 0px"><span style="color: green">&lt;/Target&gt;</span></p>
<p style="margin: 0px"><span style="color: green">&lt;Target Name=&quot;AfterBuild&quot;&gt;</span></p>
<p style="margin: 0px"><span style="color: green">&lt;/Target&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#8211;&gt;</span></p>
</p></div>
<p>For now, we&#8217;ll uncomment the BeforeBuild target and insert a task to run xsd.exe. But since this is logically better off as its own target (<em>e.g.</em> GenerateSerializationClasses), we&#8217;ll specify that the BeforeBuild target depends on another target of our creation.</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">BeforeBuild</span>&quot;<span style="color: blue"> </span><span style="color: red">DependsOnTargets</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>I&#8217;ve placed the above lines right above the comments that discuss the BeforeBuild and AfterBuild targets (&quot;To modify your build process, add your task&#8230;&quot;). Now&#8230;to actually do something inside GenerateSerializationClasses requires the use of the Exec task, which as its name implies, will execute a task as if running it from the command line. Here we need to run xsd.exe, so we need to find where this tool is located. To do this easily, run &quot;where xsd.exe&quot; from a Visual Studio Command Prompt. My xsd.exe is in one of the Windows SDK directories, so I&#8217;ll add it to the Exec task like this:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Exec</span><span style="color: blue"> </span><span style="color: red">Command</span><span style="color: blue">=</span>&quot;<span style="color: red">&amp;quot;</span><span style="color: blue">C:Program FilesMicrosoft SDKsWindowsv6.0Binxsd.exe</span><span style="color: red">&amp;quot;</span><span style="color: blue"> SampleSchema.xsd /classes</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>Straightforward, right? The Exec task tells MSBuild to run xsd.exe using the specified command parameters, which will generate serialization classes based off my XSD file (SampleSchema.xsd). If you reload and rebuild your project, then you&#8217;ll see the serialization classes appear in the .cs file you provided. But there&#8217;s one more thing we can do here first! It makes sense that we want to generate classes only when the schema file has actually changed, so we&#8217;ll need a few more attributes to the GenerateSerializationClasses target. The <em>Inputs</em> attribute specifies the inputs to consider for the target, and the <em>Outputs</em> attribute specifies the outputs to consider for the target. MSBuild will use this data to determine whether to run the target at all. Here, our logic is simple: if the schema file has been modified after the last modified time of the class file, then run the target, and that&#8217;s exactly what MSBuild will do. The final XML snippet:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue"> </span><span style="color: red">Inputs</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.xsd</span>&quot;<span style="color: blue"> </span><span style="color: red">Outputs</span><span style="color: blue">=</span>&quot;<span style="color: blue">SampleSchema.cs</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Exec<span style="color: #0000ff"> </span></span><span style="color: red">Command</span><span style="color: blue">=</span>&quot;<span style="color: red">&amp;quot;</span><span style="color: blue">C:Program FilesMicrosoft SDKsWindowsv6.0Binxsd.exe</span><span style="color: red">&amp;quot;</span><span style="color: blue"> SampleSchema.xsd /classes</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span><span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&quot;<span style="color: blue">BeforeBuild</span>&quot;<span style="color: blue"> </span><span style="color: red">DependsOnTargets</span><span style="color: blue">=</span>&quot;<span style="color: blue">GenerateSerializationClasses</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Target</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;!&#8211;</span><span style="color: green"> To modify your build process, add your task inside one of the targets below and uncomment it. </span></p>
<p style="margin: 0px"><span style="color: green">Other similar extension points exist, see Microsoft.Common.targets.</span></p>
<p style="margin: 0px"><span style="color: green">&lt;Target Name=&quot;BeforeBuild&quot;&gt;</span></p>
<p style="margin: 0px"><span style="color: green">&lt;/Target&gt;</span></p>
<p style="margin: 0px"><span style="color: green">&lt;Target Name=&quot;AfterBuild&quot;&gt;</span></p>
<p style="margin: 0px"><span style="color: green">&lt;/Target&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#8211;&gt;</span></p>
</p></div>
<p>Now, if you reload and rebuild your project, you can see the fruits of your labor:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image3.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="544" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/07/image-thumb3.png" width="648" border="0" /></a></p>
<p>We&#8217;ve generated the code, but it&#8217;s not the nicest output. Our classes have camel-cased names to match our element names, and the comments are non-existent for classes and publicly exposed members. Of course, we didn&#8217;t add any comments in our XML schema, but even if we used the xs:documentation element to document our elements and attributes, those comments <em>would not</em> be carried across to the generated code.</p>
<p>Next time, I&#8217;ll show you how to remedy these and other problems by building your own MSBuild task that can generate the same quality of code as xsd.exe but with a few custom enhancements.</p>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/07/08/generate-serialization-classes-as-part-of-your-build-part-1/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PostSharp RC2 Released (And Code Analysis&#8230;)</title>
		<link>http://davedewinter.com/2008/02/24/postsharp-rc2-released-and-code-analysis/</link>
		<comments>http://davedewinter.com/2008/02/24/postsharp-rc2-released-and-code-analysis/#comments</comments>
		<pubDate>Sun, 24 Feb 2008 16:29:21 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[Code Analysis]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[PostSharp]]></category>
		<category><![CDATA[Visual Studio Team Suite]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/?p=50</guid>
		<description><![CDATA[Gael Fraiteur has released another release candidate of PostSharp, an Aspect-Oriented Programming solution for .NET. In my previous post on PostSharp, I discussed a way to work around some pesky Code Analysis errors that PostSharp incurs as a result of &#8230; <a href="http://davedewinter.com/2008/02/24/postsharp-rc2-released-and-code-analysis/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Gael Fraiteur has released another <a href="http://www.postsharp.org/blog/2008/02/announcing-postsharp-10-rc-2.html">release candidate</a> of <a href="http://www.postsharp.org/">PostSharp</a>, an Aspect-Oriented Programming solution for .NET. In my previous <a href="http://blogs.rev-net.com/ddewinter/?p=30">post</a> on PostSharp, I discussed a way to work around some pesky Code Analysis errors that PostSharp incurs as a result of its post-compilation processing.</p>
<p>Unfortunately, I don&#8217;t believe adding the CompilerGeneratedAttribute (CGA), which was done before RC2&#8242;s release, to PostSharp-specific code fixed all of the Code Analysis warnings that our team received. After upgrading to RC2, Code Analysis warned us specifically about initializing our static fields inline in many of our classes and removing the explicit static constructors, as well as the cyclomatic complexity of some of our methods. It was the fact that we <em>did</em> initialize our static fields inline that tipped us off about the same problems that caused me to write my first <a href="http://blogs.rev-net.com/ddewinter/?p=30">PostSharp and Code Analysis</a> post. The problem is that adding the CGA is not comprehensive enough to suppress all code analysis violations. For example, PostSharp effectively injects code at certain points in a program execution (join points in a method). You wouldn&#8217;t want the CompilerGeneratedAttribute applied to that code, because it could suppress other rule violations that come from <em>your code</em>, not PostSharp&#8217;s code. Fortunately PostSharp does <em>not</em> apply the CGA in those circumstances, but there needs to be a middle ground such that PostSharp code is totally ignored by code analysis.</p>
<p><span id="more-84"></span></p>
<p>Looking ahead, I&#8217;m not sure what the best solution for the PostSharp team is on this. I know it&#8217;s low priority compared to other functionality, but as an end user it is frustrating to filter rule violations based on what PostSharp generates. The easiest approach, in my opinion, would be for PostSharp to preserve the assembly the compiler produces. That way, Visual Studio Team Edition for Developers (or Visual Studio Team Suite) can perform static code analysis on those assemblies, and FxCop can have an assembly on disk to analyze.</p>
<p>Since there were some changes in the targets file that PostSharp uses, I had to make a new version of the targets file I showed last time. This time, however, I took the opportunity to fix a bug that the old targets file introduced, which ran code analysis on PostSharp-affected code in certain circumstances.</p>
<p>Last time after using the new targets file, if you ran code analysis (using, for example, the context menu commands &#8220;Run Code Analysis&#8221; or &#8220;Rebuild&#8221; if code analysis was enabled) on a project, then everything would run as expected. Code analysis would show only warnings from the assembly before PostSharp &#8220;touched&#8221; it. The problem was that Code Analysis (CA) would run, and then PostSharp would overwrite the assembly that it analyzed. If the project were built again without any modifications to any file in the assembly, then CA would see that the assembly changed (because PostSharp overwrote it during the last build), and thus would run again.</p>
<p>The new solution takes advantage of the fact that PostSharp also stores the assembly that contains AOP-processed code in the obj$(Configuration)PostSharp directory. This is new process:</p>
<ol>
<li>Compiler runs and places assembly and PDB in obj$(Configuration) folder.</li>
<li>Code Analysis runs on obj$(Configuration) DLL.</li>
<li>PostSharp disassembles and reassembles DLL in the obj$(Configuration) folder, placing result DLL and PDB in the obj$(Configuration)PostSharp folder. Note that PostSharp <em>does not</em> ovewrite the obj$(Configuration) DLL and PDB.</li>
<li>CopyFilesToOutputDirectory copies files from obj$(Configuration) to bin$(Configuration), including the DLL and PDB. Obviously, we want the PostSharp code, not the code created straight from the compiler.</li>
<li>CopyPostSharpFilesToOutputDirectory (a new MSBuild target) copies the DLL and PDB from obj$(Configuration)PostSharp to the bin$(Configuration) folder.</li>
</ol>
<p>This process leaves the obj$(Configuration) DLL and PDB as the one that the compiler created. This gives CA a chance to run on an &#8220;untouched&#8221; assembly, both inside and outside the build process.</p>
<p>The latest targets file is available here: (Remember to rename the extension to .targets instead of .targets.xml)</p>
<p><a href="http://dev.rev-net.com/blog/ddewinter/wp-content/uploads/2008/02/postsharp-10targets.xml" title="PostSharp-1.0 Targets (RC2)">PostSharp-1.0 Targets (RC2)</a> &#8211; Copy to your %PROGRAMFILES%MSBuildPostSharp directory.</p>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/02/24/postsharp-rc2-released-and-code-analysis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PostSharp + Code Analysis = Abomination</title>
		<link>http://davedewinter.com/2008/01/15/postsharp-code-analysis-abomination/</link>
		<comments>http://davedewinter.com/2008/01/15/postsharp-code-analysis-abomination/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 01:25:33 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[Code Analysis]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[PostSharp]]></category>
		<category><![CDATA[Visual Studio Team Suite]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[Orcas]]></category>
		<category><![CDATA[Targets]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://dev.rev-net.com/blog/ddewinter/?p=30</guid>
		<description><![CDATA[(If you just want the targets files, click here.) Are you using PostSharp for your .NET development? Do you get frustrated when code analysis within VSTS reports warnings like these: Now PostSharp is a superb AOP tool for .NET, but &#8230; <a href="http://davedewinter.com/2008/01/15/postsharp-code-analysis-abomination/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>(If you just want the targets files, click <a href="http://blogs.rev-net.com/ddewinter/?p=30#targets">here</a>.)</p>
<p>Are you using <a title="PostSharp - Bringing AOP to .NET" href="http://www.postsharp.org/">PostSharp</a> for your .NET development? Do you get frustrated when code analysis within VSTS reports warnings like these:</p>
<p style="text-align: center" align="left"><img alt="Code Analysis Warnings" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/01/postsharp_ca_warnings.png" /></p>
<p>Now PostSharp is a superb AOP tool for .NET, but it is annoying to see these issues in code analysis again and again; what would be great is if we can edit the build process to make Code Analysis (CA) run <em>before</em> PostSharp processes the assembly. That way, code analysis errors on PostSharp-generated code is ignored, and everyone is happy. <img class="wp-smiley" alt=":)" src="http://blogs.rev-net.com/ddewinter/wp-includes/images/smilies/icon_smile.gif" /></p>
<p> <span id="more-80"></span><span id="more-30"></span>
</p>
<p>It can take a while to parse through all the targets in Microsoft.Common.targets, Microsoft.CodeAnalysis.targets, and PostSharp-1.0.targets, but here&#8217;s the general order of what&#8217;s happening with a fresh PostSharp installation.</p>
<ul>
<li>&#8230; </li>
<li>Compile
<ul>
<li>&#8230; </li>
<li>CoreCompile (Delegated to a specific language&#8217;s targets file; for example, C# runs csc.exe at this point.) </li>
<li>&#8230; </li>
<li>PostSharpInspectConstants </li>
<li>PostSharpInspectReferences </li>
<li>PostSharp (Where the actual post-compilation is done) </li>
</ul>
</li>
<li>&#8230; </li>
<li>PrepareForRun (After build, but before running the application)
<ul>
<li>CopyFilesToOutputDirectory </li>
<li>RunCodeAnalysis </li>
</ul>
</li>
<li>&#8230; </li>
</ul>
<p>So there are obviously a couple of steps between the PostSharp processing and CA. When building the project, the CoreCompile target will place the newly built assembly in the obj$(Configuration) folder. Afterwards, when PostSharp runs, it compiles a new assembly with PDBs in the obj$(Configuration)PostSharp folder. Finally, that is copied to the obj$(Configuration) folder, which overwrites what the CoreCompile task created.</p>
<p>CA waits until the files are copied to the $(OutDir) directory (which is by default bin$(Configuration)) before executing. Thus it would be great if we could now change the order of things to do the following when PostSharp is enabled:</p>
<ul>
<li>&#8230; </li>
<li>Compile
<ul>
<li>&#8230; </li>
<li>CoreCompile (Delegated to a specific language&#8217;s targets file; for example, C# runs csc.exe at this point.) </li>
<li>&#8230; </li>
<li><em>RunCodeAnalysis</em> </li>
<li>PostSharpInspectConstants </li>
<li>PostSharpInspectReferences </li>
<li>PostSharp </li>
</ul>
</li>
<li>&#8230; </li>
<li>PrepareForRun
<ul>
<li>CopyFilesToOutputDirectory </li>
</ul>
</li>
<li>&#8230; </li>
</ul>
<p>So the next question is how do we do that?</p>
<p>The first thing is we need to find the targets files for both CA and PostSharp. The former is located at %PROGRAMFILES%MSBuildMicrosoftVisualStudiov9.0CodeAnalysisMicrosoft.CodeAnalysis.targets, and the latter is located at %PROGRAMFILES%MSBuildPostSharpPostSharp-1.0.targets. At the end of the PostSharp targets file, you can see that it inserts itself into the chain of compilation targets I described above.</p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(CompileDependsOn);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectConstants;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectReferences;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharp</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">BuildDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(BuildDependsOn);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpVerify</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">BuildDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p>Now perhaps we can trick code analysis into running before PostSharp just by re-ordering the dependencies, like this:</p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(CompileDependsOn);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <strong>RunCodeAnalysis</strong>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectConstants;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectReferences;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharp</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">BuildDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(BuildDependsOn);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpVerify</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">BuildDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p>So we&#8217;ve said to run code analysis before the PostSharp processing. Unfortunately, this doesn&#8217;t work, as MSBuild reports the following error:</p>
<p style="text-align: center"><img alt="MSBuild Circular Dependency" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/01/circular_dependency.png" /></p>
<p>If we navigate to the Microsoft.CodeAnalysis.targets file, we can see that the RunCodeAnalysis target depends on the Compile target. But because we also overrode the CompileDependsOn property to include RunCodeAnalysis, we have two targets that are dependent on each other to run.</p>
<p>The next trick is to change what CodeAnalysis is dependent on. To do this, we need to change its semantics; instead of performing analysis on the $(OutDir)$(TargetName)$(TargetExt)&#160; file (<em>e.g.</em> binDebugTarget.dll), we need to perform analysis on the obj$(Configuration)$(TargetName)$(TargetExt) file (<em>e.g.</em> objDebugTarget.dll). So instead of being dependent on Compile, the target is dependent on the step that generates the objDebugTarget.dll file: CoreCompile.</p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Target</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">RunCodeAnalysis</span>&#8220;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; </span><span style="color: red">Condition</span><span style="color: blue">=</span>&#8220;<span style="color: blue">&#8216;$(RunCodeAnalysis)&#8217;==&#8217;true&#8217; or &#8216;$(RunCodeAnalysisOnce)&#8217;==&#8217;true&#8217;</span>&#8220;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; </span><span style="color: red">Inputs</span><span style="color: blue">=</span>&#8220;<span style="color: blue">$(CodeAnalysisInputAssemblyForTask)</span>&#8220;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; </span><span style="color: red">Outputs</span><span style="color: blue">=</span>&#8220;<span style="color: blue">$(CodeAnalysisLogFileForTask);$(CodeAnalysisSucceededFile)</span>&#8220;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; </span><span style="color: red">DependsOnTargets</span><span style="color: blue">=</span>&#8220;<span style="color: blue">CoreCompile;SetCodeAnalysisProperties</span>&#8220;</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &gt;</span></p>
<p>We&#8217;re almost done. Unfortunately, now CodeAnalysis runs at the correct point, but it doesn&#8217;t run on the correct file. Remember we want it to perform analysis on the obj$(Configuration) assembly before PostSharp has overwritten it.&#160; So how does Code Analysis know where to retrieve the assembly? Well, if we open the Microsoft.CodeAnalysis.targets file again and have a look at the properties, we can see:</p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue"> </span><span style="color: red">Condition</span><span style="color: blue">=</span>&#8220;<span style="color: blue">&#8216;$(CodeAnalysisInputAssembly)&#8217;!=&#8221;</span>&#8220;<span style="color: blue">&gt;</span>$(CodeAnalysisInputAssembly)<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue"> </span><span style="color: red">Condition</span><span style="color: blue">=</span>&#8220;<span style="color: blue">&#8216;$(CodeAnalysisInputAssembly)&#8217;==&#8221;</span>&#8220;<span style="color: blue">&gt;</span>$(OutDir)$(TargetName)$(TargetExt)<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue"> </span><span style="color: red">Condition</span><span style="color: blue">=</span>&#8220;<span style="color: blue">&#8216;$(CodeAnalysisLogFile)&#8217;!=&#8221;</span>&#8220;<span style="color: blue">&gt;</span>$(CodeAnalysisLogFile)<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue"> </span><span style="color: red">Condition</span><span style="color: blue">=</span>&#8220;<span style="color: blue">&#8216;$(CodeAnalysisLogFile)&#8217;==&#8221;</span>&#8220;<span style="color: blue">&gt;</span>$(CodeAnalysisInputAssemblyForTask).CodeAnalysisLog.xml<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue">&gt;</span></p>
<p>So what this tells us is that the CodeAnalysisInputAssemblyForTask and CodeAnalysisLogFileForTask files can be overridden by a project file or another targets file by specifying either property in a &lt;PropertyGroup&gt; tag, like this:</p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue">&gt;</span>obj$(Configuration)$(TargetName)$(TargetExt)<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue">&gt;</span>$(CodeAnalysisInputAssemblyForTask).CodeAnalysisLog.xml<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p>When placed in a project file, this will instruct Code Analysis to analyze the assembly that we want and to produce the log file in the correct directory. This is a bit of a hassle when you have to change every single project, and there may be some cases where you want to keep the default behavior of Code Analysis (i.e. point at the binDebug folder when PostSharp is not run). There is one last tweak we can make to automate this change across all projects. Open up the PostSharp targets file and scroll down to the PropertyGroup that defines the CompileDependsOn property. Overwrite that single property group with the following:</p>
<p style="margin: 0px"><span style="color: blue">&lt;!&#8211;</span><span style="color: green"> Introduces PostSharp in the chain of compilation targets </span><span style="color: blue">&#8211;&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue"> </span><span style="color: red">Condition</span><span style="color: blue">=</span>&#8220;<span style="color: blue">&#8216;$(RunCodeAnalysis)&#8217;==&#8217;true&#8217; or &#8216;$(RunCodeAnalysisOnce)&#8217;==&#8217;true&#8217;</span>&#8220;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(CompileDependsOn);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; RunCodeAnalysis;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectConstants;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectReferences;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharp</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue">&gt;</span>obj$(Configuration)$(TargetName)$(TargetExt)<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisInputAssemblyForTask</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue">&gt;</span>$(CodeAnalysisInputAssemblyForTask).CodeAnalysisLog.xml<span style="color: blue">&lt;/</span><span style="color: #a31515">CodeAnalysisLogFileForTask</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue"> </span><span style="color: red">Condition</span><span style="color: blue">=</span>&#8220;<span style="color: blue">&#8216;$(RunCodeAnalysis)&#8217;!=&#8217;true&#8217; and &#8216;$(RunCodeAnalysisOnce)&#8217;!=&#8217;true&#8217;</span>&#8220;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(CompileDependsOn);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectConstants;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpInspectReferences;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharp</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">CompileDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">BuildDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(BuildDependsOn);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; PostSharpVerify</p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">BuildDependsOn</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">PropertyGroup</span><span style="color: blue">&gt;</span></p>
<p><a id="targets"></a></p>
<p>This final edit makes the targets a little more robust in that we (1) schedule Code Analysis to run before PostSharp only when CA is enabled and we (2) edit the CA Input Assembly property to target the desired location.</p>
<p>Here are the final targets files (Be sure to rename them to .targets instead of .xml):</p>
<p><a title="PostSharp-1.0 Targets" href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/01/PostSharp-1.0.targets.xml">PostSharp-1.0 Targets</a> &#8211; %PROGRAMFILES%MSBuildPostSharp</p>
<p><a title="Code Analysis VSTS 9.0 Targets" href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/01/Microsoft.CodeAnalysis.Targets.xml">Code Analysis VSTS 9.0 Targets</a> &#8211; %PROGRAMFILES%MSBuildMicrosoftVisualStudiov9.0CodeAnalysis</p>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/01/15/postsharp-code-analysis-abomination/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

