<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.3" --><rss 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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" version="2.0">

<channel>
	<title>Oleg Sych</title>
	<link>http://www.olegsych.com</link>
	<description>Me.Write(code)</description>
	<pubDate>Thu, 05 Nov 2009 15:20:14 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.3</generator>
	<language>en</language>
			<creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-sa/2.5/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>T4 Toolbox: Support for Visual Studio 2010</title>
		<link>http://www.olegsych.com/2009/10/t4-toolbox-support-for-visual-studio-2010/</link>
		<comments>http://www.olegsych.com/2009/10/t4-toolbox-support-for-visual-studio-2010/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 16:55:10 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Code Generation]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/10/t4-toolbox-support-for-visual-studio-2010/</guid>
		<description><![CDATA[As of version 9.10, T4 Toolbox now supports Visual Studio 2010 in addition to Visual Studio 2008.]]></description>
			<content:encoded><![CDATA[<p>As of version <a href="http://t4toolbox.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=30030">9.10</a>, <a href="http://t4toolbox.codeplex.com" target="_blank">T4 Toolbox</a> now supports Visual Studio 2010 in addition to Visual Studio 2008. You can now create both traditional and <a href="http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/">preprocessed templates</a> that utilize the advanced functionality the Toolbox offers to generate multiple output files, add them to different projects and more.</p>
<p>The set of project item templates has been extended to support preprocessed templates and generators. Here is what you will see when you add a new item to a Visual Basic project. </p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.olegsych.com/wp-content/uploads/2009/10/image.png" width="580" height="326" /> </p>
<p>This list contains familiar project item templates, such as <em>Template, Generator </em>and <em>Unit Test. Script </em>is the project item template that was previously named <em>File</em>. It is a traditional .tt file that is meant to include other, partial .tt files such as <em>Template</em> and <em>Generator</em>. Hopefully the new name <em>Script </em>makes more sense than <em>File</em>. </p>
<p>The list of project item templates for Visual C# projects is similar and also includes ready-to-use code generators written in C#. It is the same with the exception of the <a href="http://www.olegsych.com/2008/07/t4-template-for-generating-sql-view-from-csharp-enumeration">Enum SQL View</a>, which at this time works only in Visual Studio 2008.</p>
<h4>Preprocessed Templates and Generators</h4>
<p><em>Preprocessed Template </em>and <em>Preprocessed Generator</em> project item templates, which are similar to the traditional <em>Template </em>and <em>Generator</em> respectively, were added take advantage of the new capability offered by Visual Studio 2010 to <a href="http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/">preprocess .tt files</a> and compile T4-based code generators in .NET assemblies. </p>
<p>When you add a <em>Preprocessed Template</em> to your project, two files get created - a preprocessed .tt file and a partial .cs or .vb file similar to the ones below.</p>
<h6>Template.tt (C#)</h6>
<pre class="code"><span style="color: black">&lt;#@ </span><span style="color: brown">template </span><span style="color: red">language</span><span style="color: black">=&quot;</span><span style="color: blue">C#</span><span style="color: black">&quot; </span><span style="color: red">inherits</span><span style="color: black">=&quot;</span><span style="color: blue">T4Toolbox.Template</span><span style="color: black">&quot; #&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Template.partial.cs</h6>
<pre class="code"><span style="color: blue">namespace </span>ClassLibrary1
{
    <span style="color: blue">using </span>System;
    <span style="color: blue">using </span>T4Toolbox;

    <span style="color: blue">public partial class </span><span style="color: #2b91af">Template1
    </span>{
        <span style="color: blue">protected override void </span>Validate()
        {
            <span style="color: blue">this</span>.Warning(<span style="color: #a31515">&quot;Template properties have not been validated&quot;</span>);
        }
    }
}</pre>
<h5>Template.tt (Visual Basic)</h5>
<pre class="code"><span style="color: black">&lt;#@ </span><span style="color: brown">template </span><span style="color: red">language</span><span style="color: black">=&quot;</span><span style="color: blue">VB</span><span style="color: black">&quot; </span><span style="color: red">inherits</span><span style="color: black">=&quot;</span><span style="color: blue">T4Toolbox.Template</span><span style="color: black">&quot; #&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Template.partial.vb</h6>
<pre class="code"><span style="color: blue">Imports </span>T4Toolbox

<span style="color: blue">Partial Public Class </span><span style="color: #2b91af">Template1
    </span><span style="color: blue">Inherits </span><span style="color: #2b91af">Template

    </span><span style="color: blue">Protected Overrides Sub </span>Validate()
        <span style="color: blue">Me</span>.Warning(<span style="color: #a31515">&quot;Template properties have not been validated&quot;</span>)
    <span style="color: blue">End Sub

End Class</span></pre>
<p>For preprocessed .tt files, T4 doesn’t generate actual output; instead it generates the code generation template itself. Here is a cleaned-up version of what you will see if you open the files generated by TextTemplatingFilePreprocessor.</p>
<h6>Template.cs</h6>
<pre class="code"><span style="color: blue">namespace </span>ClassLibrary1
{
    <span style="color: blue">using </span>System;
    <span style="color: blue">using </span>System.CodeDom.Compiler;

    <span style="color: blue">#line </span>1 &quot;C:\&#8230;\Template1.tt&quot;
    [<span style="color: #2b91af">GeneratedCodeAttribute</span>(<span style="color: #a31515">&quot;Microsoft.VisualStudio.TextTemplating&quot;</span>, <span style="color: #a31515">&quot;10.0.0.0&quot;</span>)]
    <span style="color: blue">public partial class </span><span style="color: #2b91af">Template1 </span>: T4Toolbox.<span style="color: #2b91af">Template
    </span>{
        <span style="color: blue">public override string </span>TransformText()
        {
            <span style="color: blue">return this</span>.GenerationEnvironment.ToString();
        }
    }

    <span style="color: blue">#line </span>default
    <span style="color: blue">#line </span>hidden
}</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<h6>Template.vb</h6>
<pre class="code"><span style="color: blue">Imports </span>System
<span style="color: blue">Imports </span>System.CodeDom.Compiler

&lt;<span style="color: #2b91af">GeneratedCodeAttribute</span>(<span style="color: #a31515">&quot;Microsoft.VisualStudio.TextTemplating&quot;</span>, <span style="color: #a31515">&quot;10.0.0.0&quot;</span>)&gt; _
<span style="color: blue">Partial Public Class </span><span style="color: #2b91af">Template1
    </span><span style="color: blue">Inherits </span>T4Toolbox.<span style="color: #2b91af">Template
    </span><span style="color: blue">Public Overrides Function </span>TransformText() <span style="color: blue">As String
        Return Me</span>.GenerationEnvironment.ToString
    <span style="color: blue">End Function
End Class</span></pre>
<p>Together, <em>Template</em> and <em>Template.partial </em>files define a single class that descends from <em>T4Toolbox.Template</em> which I assume is already familiar to the reader. In a traditional T4 Toolbox <em>Template</em>, you would place all logic in a single .tt file, using a mix of <a href="http://www.olegsych.com/2008/02/t4-text-blocks/">text blocks</a> and <a href="http://www.olegsych.com/2008/02/t4-class-feature-blocks/">class feature blocks</a>. With a <em>preprocessed</em> template, you will typically want to use the .tt file only for the logic that requires text templating. Non-templating logic, such as validation, properties, utility methods, etc. can be placed in the partial .cs/.vb file. This helps to reduce complexity of .tt files by isolating “presentation” code that requires text templating in its own file where it is not mixed with the class definition and model access code. </p>
<p>Despite of what their name implies, <em>Preprocessed Generator</em> project items are not .tt files. A traditional <em>Generator</em> is typically defined in a single <a href="http://www.olegsych.com/2008/02/t4-class-feature-blocks/">class feature block</a> of a .tt file, does not use any text templating features and uses one or more traditional <em>Templates</em> to generate output files. Similarly, a <em>Preprocessed Generator</em> is a simple .cs/.vb file that contains a <em>Generator </em>class definition and uses one or more <em>Preprocessed Templates </em>to generate output files. Here is what it looks like.</p>
<h6>C#</h6>
<pre class="code"><span style="color: blue">namespace </span>ClassLibrary1
{
    <span style="color: blue">using </span>System;
    <span style="color: blue">using </span>T4Toolbox;

    <span style="color: blue">public class </span><span style="color: #2b91af">Generator1 </span>: <span style="color: #2b91af">Generator
    </span>{
        <span style="color: blue">protected override void </span>RunCore()
        {

        }

        <span style="color: blue">protected override void </span>Validate()
        {
            <span style="color: blue">this</span>.Warning(<span style="color: #a31515">&quot;Generator properties have not been validated&quot;</span>);
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code"><span style="color: blue">Imports </span>T4Toolbox

<span style="color: blue">Public Class </span><span style="color: #2b91af">Generator1
    </span><span style="color: blue">Inherits </span><span style="color: #2b91af">Generator

    </span><span style="color: blue">Protected Overrides Sub </span>RunCore()

    <span style="color: blue">End Sub

    Protected Overrides Sub </span>Validate()
        <span style="color: blue">Me</span>.Warning(<span style="color: #a31515">&quot;Generator properties have not been validated&quot;</span>)
    <span style="color: blue">End Sub

End Class</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Just like in a traditional generator, you would typically define several properties and override <em>RunCore </em>and <em>Validate </em>methods.</p>
<h4>T4Toolbox.Template Class Has a Breaking Change</h4>
<p>In order to be compatible with template preprocessing in Visual Studio 2010, interface and implementation of the <em>T4Toolbox.Template</em> class had to change. <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.texttransformation.transformtext.aspx">TransformText</a> method used to have a sealed implementation that called the abstract <em>RenderCore </em>method you had to override in the descendants. Now the <em>TransformText</em> method itself is abstract and serves the purpose of <em>RenderCore</em> which has been removed.</p>
<p>This is a breaking change for any existing <em>traditional</em> Template classes you may have. Here is an example of a Template implementation you had before.</p>
<h6>C#</h6>
<pre class="code"><span style="color: black">&lt;#+
</span><span style="color: blue">public class </span><span style="color: black">Template2 : Template
{
    </span><span style="color: blue">public override void </span><span style="color: black">RenderCore()
    {
        </span><span style="color: green">// Text blocks and code generation logic
        // &#8230;
    </span><span style="color: black">}
}
#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code"><span style="color: black">&lt;#+
</span><span style="color: blue">Public Class </span><span style="color: black">Template2
    </span><span style="color: blue">Inherits </span><span style="color: black">Template

    </span><span style="color: blue">Public Overrides Sub </span><span style="color: black">RenderCore()
        </span><span style="color: green">&#8216; Text blocks and code generation logic
        &#8216; &#8230;
    </span><span style="color: blue">End Sub

End Class
</span><span style="color: black">#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>And here is an example of a Template implementation you have to have now.</p>
<h6>C#</h6>
<pre class="code"><span style="color: black">&lt;#+
</span><span style="color: blue">public class </span><span style="color: black">Template2 : Template
{
    </span><span style="color: blue">public override string </span><span style="color: black">TransformText()
    {
        </span><span style="color: green">// Text blocks and code generation logic
        // &#8230;
        </span><span style="color: blue">return this</span><span style="color: black">.GenerationEnvironment.ToString();
    }
}
#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code"><span style="color: black">&lt;#+
</span><span style="color: blue">Public Class </span><span style="color: black">Template2
    </span><span style="color: blue">Inherits </span><span style="color: black">Template

    </span><span style="color: blue">Public Overrides Function </span><span style="color: black">TransformText() </span><span style="color: blue">As String
        </span><span style="color: green">&#8216; Text blocks and code generation logic
        &#8216; &#8230;
        </span><span style="color: blue">Return Me</span><span style="color: black">.GenerationEnvironment.ToString()
    </span><span style="color: blue">End Function

End Class
</span><span style="color: black">#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a>In order to be compatible with the new version of T4 Toolbox, all existing Template implementations need to be modified to a) replace each RenderCore method override with a TransformText method override and b) return <a href="http://msdn.microsoft.com/en-us/library/Microsoft.VisualStudio.TextTemplating.TextTransformation.GenerationEnvironment.aspx" target="_blank">GenerationEnvironment</a>.ToString() at the end of the method.</p>
<p><em>Template </em>class now provides a new method called <em>Transform</em>, which returns a string and serves the same purpose as TransformText implementation served previously. Just like <em>TransformText</em>, this method is not intended to be called directly by code in your <em>Generator </em>or <em>Script</em> code, where you would normally call <em>Render </em>or <em>RenderToFile</em><em>.</em> You would only call <em>TransformText </em> (and now <em>Transform</em>) method in unit testing code to validate code generation results without creating the output files. If you have any code that calls the now abstract <em>TransformText </em>method, change it to call the new <em>Transform </em>instead.</p>
<p>Introducing this breaking change was not an easy decision. It was necessary to “unseal” implementation of the <em>TransformText</em> in order to make T4 Toolbox compatible with TextTemplatingFilePreprocessor in Visual Studio 2010 which assumes that this method is abstract. Although it would have been possible to keep backward compatibility, it would result in confusing design and implementations working differently in traditional and preprocessed templates. Taking into consideration the effort required to maintain this going forward, <a href="http://t4toolbox.codeplex.com/Thread/View.aspx?ThreadId=70559">we made a decision</a> to go ahead and convert existing templates now and leave this change behind. </p>
<p>The changes required to upgrade existing code are straightforward. You can use the “Find in Files” feature in Visual Studio to find all instances of <em>RenderCore </em>methods that need to be converted to <em>TransformText</em>. This is a manual change as it requires you to add a return statement at the end of each method. Replacing calls to <em>TransformText </em>method with Transform can be safely accomplished using the “Find and Replace” across multiple files. Including code changes, running unit tests and resolving errors, <a href="http://t4toolbox.codeplex.com/SourceControl/changeset/view/37331">this change</a> took less than an hour with the existing code generators in T4 toolbox itself.</p>
<h4>Under the Hood</h4>
<p>In order to make <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> Toolbox compatible with both Visual Studio 2008 and Visual Studio 2010, we now have to separate assemblies: T4Toolbox.dll, a .NET 3.5 assembly which is used in Visual Studio 2008, and T4Toolbox.10.0.dll, a .NET 4.0 assembly which is used in Visual Studio 2010. Introducing a separate new binary was required because Microsoft.VisualStudio.TextTemplating assembly in Visual Studio 2010 has been renamed to Microsoft.VisualStudio.TextTemplating.10.0, which means that <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.texttransformation.aspx">TextTransformation</a> base class in Visual Studio 2010 is now physically different than the same class in Visual Studio 2008, forcing you to have separate binaries for descendants.</p>
<p>Producing a .NET 4.0 version of the T4Toolbox assembly required a complete overhaul of the build system. The project files had to be upgraded to Visual Studio 2010. To keep complexity under control and have a single set of project files, they had to be hacked to generate an assembly with different target .NET framework versions depending on build configuration. This had to be done directly in the project files because target framework is exposed as a project-level setting by Visual Studio 2010.</p>
<p>Microsoft SDC tasks don’t appear to support MSBuild 4.0 at this time and generation of Visual Studio project item templates had to be changed to use MSBuild extensions in the DSL SDK. </p>
<p>Because of these changes, the previously published instructions on how to <a title="Getting and compiling T4 Toolbox source code" href="http://www.olegsych.com/2009/06/getting-and-compiling-t4-toolbox-source-code/">get and compile T4 Toolbox source code</a> are now incorrect. I will not go back and update these instructions until we have a release version of Visual Studio 2010 and things settle down a bit.</p>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/ccGGA_t_0XQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/10/t4-toolbox-support-for-visual-studio-2010/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Understanding T4: Preprocessed Text Templates</title>
		<link>http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/</link>
		<comments>http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 00:26:54 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[Template]]></category>

		<category><![CDATA[Visual Basic]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/</guid>
		<description><![CDATA[This article provides an overview of preprocessed text templates in Visual Studio 2010 and includes detailed description of differences between preprocessed and traditional text templates.]]></description>
			<content:encoded><![CDATA[<p>As you already know, <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> engine performs two steps when generating output from a template.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Template Transformation Process" border="0" alt="Template Transformation Process" src="http://www.olegsych.com/wp-content/uploads/2009/09/image.png" width="570" height="311" /> </p>
<p>During the first step, the engine preprocesses the template: it parses the processing instructions, text and code blocks, generates a concrete <a href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.texttransformation.texttransformation.aspx">TextTransformation</a> class, and compiles it into a .NET assembly. During the second step, T4 engine creates an instance of the <em>GeneratedTextTransformation</em> class, calls its <em>TransformText </em>method and saves the string it returns to the output file.</p>
<p>Visual Studio 2010 also allows you to preprocess the template at design time, when <em>author</em> of the code generator creates the template itself. At run time, when a <em>developer</em> is using template to generate output code, the hosting application simply creates an instance of the precompiled <em>GeneratedTextTransformation</em> and uses it to generate output as usual. Because preprocessed templates have no hard-coded dependency on Visual Studio, any application can host preprocessed templates, as long as it provides appropriate mechanism for saving or presenting the generated output to the user.</p>
<p>At the time of this writing, no official information is available about preprocessed text templates on <a href="http://msdn.microsoft.com/en-us/library/bb126445(VS.100).aspx">MSDN</a>. Gareth Jones and Pablo Galiano published useful information on their blogs (see the References section below). This article is meant to fill the gaps and serve as a comprehensive overview and reference of the functionality supported by preprocessed templates. </p>
<h4>Creating a Preprocessed Template</h4>
<ul>
<li>Create a new C# or Visual Basic project in Visual Studio 2010. </li>
<li>Select Project -&gt; Add New Item from the main menu </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Adding Preprocessed Text Template to a Visual Basic Project" border="0" alt="Adding Preprocessed Text Template to a Visual Basic Project" src="http://www.olegsych.com/wp-content/uploads/2009/09/image1.png" width="580" height="326" /> </p>
<ul>
<li>In the <em>Add New Item</em> dialog, select <em>Preprocessed Text Template</em> item, enter appropriate name and click <em>Add </em>button. </li>
<li>In <em>Solution Explorer</em>, you should now see the new .tt file and the preprocessed template file it generates. To see the preprocessed template file in a Visual Basic project, make sure to click the <em>Show All Files </em>button in the toolbar of <em>Solution Explorer.</em> </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Preprocessed Template in Solution Explorer" border="0" alt="Preprocessed Template in Solution Explorer" src="http://www.olegsych.com/wp-content/uploads/2009/09/image2.png" width="265" height="225" /> <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="File Properties of Preprocessed Template" border="0" alt="File Properties of Preprocessed Template" src="http://www.olegsych.com/wp-content/uploads/2009/09/image3.png" width="300" height="225" /></p>
<p>Note that <em>Custom Tool</em> this .tt file was associated with is <em>TextTemplatingFilePreprocessor</em>&#160; instead of the traditional <em>TextTemplatingFileGenerator</em>. Instead of the output file, which would be generated by the traditional template, for the preprocessed template, we the actual source code of the template itself added to the project. This preprocessed template class is compiled as part of the project that contains the .tt file. </p>
<ul>
<li>Modify the .tt file to look like so </li>
</ul>
<h6>C#</h6>
<pre class="code">&lt;#@ template language=&quot;C#&quot; #&gt;
Hello World</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code">&lt;#@ template language=&quot;VB&quot; #&gt;
Hello World</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<ul>
<li>Check the preprocessed template (<em>PreprocessedTextTemplate.vb </em>or <em>.cs</em>) which should look similar to this: </li>
</ul>
<h6>C#</h6>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Preprocessed Template, C#" border="0" alt="Preprocessed Template, C#" src="http://www.olegsych.com/wp-content/uploads/2009/09/image4.png" width="580" height="493" /> </p>
<h6>Visual Basic</h6>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Preprocessed Template, Visual Basic" border="0" alt="Preprocessed Template, Visual Basic" src="http://www.olegsych.com/wp-content/uploads/2009/09/image5.png" width="580" height="379" /> </p>
<p>As you can see, the <a href="http://www.olegsych.com/2008/02/t4-text-blocks/">text</a>, <a href="http://www.olegsych.com/2008/02/t4-statement-blocks/">statement</a>, <a href="http://www.olegsych.com/2008/02/t4-expression-blocks/">expression</a> and <a href="http://www.olegsych.com/2008/02/t4-class-feature-blocks/">class feature</a> blocks defined in the .tt file become a part of the preprocessed template class just like in a traditional template. However, there are several interesting points to note. </p>
<p>First of all, notice that name of the generated template class is based on the name of the .tt file. In our example, <em>PreprocessedTextTemplate.tt</em> produced class name PreprocessedTextTemplate. In a traditional template, this name would be hard-coded <em>GeneratedTextTransformation</em>. Having file name determine the class name allows us to give template classes meaningful names and organize them in class libraries.</p>
<p>The namespace in which the class is generated is based on the <em>Custom Tool Namespace</em> property of the .tt file. In Visual Basic, this property is My.Templates by default which is what you see generated in the code above. In C# this property is empty by default, causing <em>TextTemplatingFilePreprocessor</em> to construct the namespace based on the default project namespace and location of the .tt file in it. In Visual Basic, clearing the <em>Custom Tool Namespace</em> results in template class being generated in the root namespace of the project. This is also different from traditional templates, which use a hardcoded namespace with a randomly generated suffix, and also allows us to better organize the precompiled templates as part of class libraries.</p>
<p>And last, the preprocessed template class is generated as partial. You can further extend it by adding another partial .cs or .vb file to the project. This allows you to place methods and properties that don’t require templating in a regular source file instead of class feature blocks you would otherwise have to use in a traditional template. Out of the box, Visual Studio offers better debugging experience, IntelliSense and color syntax highlighting for regular source files. However, these differences are reduced only to debugging if you are using the <a href="http://www.olegsych.com/2009/04/t4-editor-by-tangible-engineering/">T4 Editor</a> to create your templates. </p>
<h4>Using a Preprocessed Template</h4>
<p>Executing a preprocessed template is a simple matter of creating an instance of the preprocessed template class and calling its <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.texttransformation.transformtext.aspx">TransformText</a> method. As Pablo Galiano describes <a href="http://www.clariusconsulting.net/blogs/pga/archive/2009/07/15/160853.aspx">here</a>, this can be done in any application. Here we will review how preprocessed templates can be used for code generation in a traditional T4 template, hosted and executed by Visual Studio.</p>
<ul>
<li>Add a traditional text template to the project </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Adding Traditional Text Template" border="0" alt="Adding Traditional Text Template" src="http://www.olegsych.com/wp-content/uploads/2009/09/image6.png" width="580" height="326" /></p>
<ul>
<li>Modify it to look like this, using full path to the assembly that contains the precompiled template and its namespace. </li>
</ul>
<h6>C#</h6>
<p><a href="http://11011.net/software/vspaste"></a></p>
<pre class="code">&lt;#@ template language=&quot;C#&quot; #&gt;
&lt;#@ output extension=&quot;txt&quot; #&gt;
&lt;#@ assembly name=&quot;C:\...\bin\Debug\CsTemplate.dll&quot; #&gt;
&lt;#@ import namespace=&quot;CsTemplate&quot; #&gt;
&lt;#
    PreprocessedTextTemplate t = new PreprocessedTextTemplate();
    this.Write(t.TransformText());
#&gt;</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code">&lt;#@ template language=&quot;VB&quot; #&gt;
&lt;#@ output extension=&quot;txt&quot; #&gt;
&lt;#@ assembly name=&quot;C:\...\bin\Debug\VbTemplate.dll&quot; #&gt;
&lt;#@ import namespace=&quot;VbTemplate.My.Templates&quot; #&gt;
&lt;#
    Dim t As PreprocessedTextTemplate = New PreprocessedTextTemplate()
    Me.Write(t.TransformText())
#&gt;</pre>
<p>As you can see, in this traditional template, we are creating a new instance of the precompiled template and writing the code it generates to the standard output file, <em>TextTemplate.txt </em>in this case.</p>
</p>
<ul>
<li>Check the output file, which should look like this. </li>
</ul>
<pre class="code">Hello World</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>For simplicity of this example, we have both the preprocessed template and the traditional template using it in the same project. In a real-world scenario, you will typically have a preprocessed template in a separate assembly, which you compile and distribute to your development team for use in other projects. </p>
<h4>Differences Between Traditional and Preprocessed Templates</h4>
<p>There are several important differences between traditional and preprocessed templates. </p>
<h5>Dependency on Microsoft.VisualStudio.TextTemplating assembly</h5>
<p>Traditional T4 templates have a dependency on Microsoft.VisualStudio.TextTemplating assembly, which is installed as part of Visual Studio and cannot be redistributed. Preprocessed templates don’t hard-code this dependency and can be used to generate code from a custom hosting application. In the example above, you can see that all code required to execute the preprocessed template is generated as part of its definition and doesn’t rely on any base classes. However, when preprocessed templates are intended for use only within Visual Studio, we can avoid having multiple redundant implementations of the same properties and methods in each template class by using Inherits parameter of the Template directive to specify the standard <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.texttransformation.aspx">TextTransformation</a> as the base class.</p>
<h5><a href="http://www.olegsych.com/2008/02/t4-template-directive/">Template Directive</a></h5>
<p><em><strong>Language </strong></em>parameter is partially supported. The precompiled template is generated in the specified language, however if template language doesn’t match the language of the project it belongs to, the generated template file will not be compiled. If this happens, the Build Action for the output file is automatically changed to <em>Content</em>.</p>
<p><em><strong>Debug </strong></em>parameter appears to have no effect on preprocessed templates. Template author is responsible for setting debugging options for the project which contains the preprocessed .tt file.</p>
<p><em><strong>Inherits</strong></em> parameter is supported and significantly changes the way preprocessed templates are generated. When this parameter is not present, the preprocessed template class will be generated without base class and will have its own implementations of all standard methods inherited by traditional templates from the <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.texttransformation.aspx">TextTransformation</a> class. When this parameter is present, the preprocessed template class will be generated with the specified base class and <em>without</em> the standard methods. Template author is responsible for specifying a base class that either inherits from TextTransformation, or provides compatible properties and methods.</p>
<p><strong><em>Hostspecific </em></strong>parameter is partially supported. The preprocessed template class is generated with the appropriate Host property, however, this introduces compile-time dependency on Microsoft.VisualStudio.TextTemplating assembly. Template author is responsible for adding a reference to this assembly to the project that contains the preprocessed template class. The hosting application is responsible for providing a value for this property at run time.</p>
<p><strong><em>Culture </em></strong>parameter appears to be fully supported.</p>
<h5><a href="http://www.olegsych.com/2008/02/t4-output-directive/">Output Directive</a></h5>
<p>The &lt;#@ output #&gt; directive appears to have no effect on preprocessed templates. No error is generated when a preprocessed template contains this directive. The hosting application is responsible for changing the extension of the output file.</p>
<h5><a href="http://www.olegsych.com/2008/02/t4-assembly-directive/">Assembly Directive</a></h5>
<p>The &lt;#@ assembly #&gt; directive appears to have no effect on preprocessed templates. No errors is generated when a preprocessed template contains this directive. Template author is responsible for adding appropriate assembly references to the project that contains the .tt file.</p>
<h5><a href="http://www.olegsych.com/2008/02/t4-import-directive/" target="_blank">Import Directive</a></h5>
<p>The &lt;#@ import #&gt; directive appears to be fully supported by the preprocessed templates. Appropriate using (C#) and imports (Visual Basic) statements are added to the generated template class.</p>
<h5><a href="http://www.olegsych.com/2008/02/t4-include-directive/" target="_blank">Include Directive</a></h5>
<p>The &lt;#@ include #&gt; directive appears to be fully supported by the preprocessed templates. Template blocks of the included files are merged appropriately in the generated template class.</p>
<h5>Custom Directives</h5>
<p>Custom directives, such as <a href="http://www.olegsych.com/2008/08/t4-xsd-directive/">&lt;#@ xsd #&gt;</a> and <a href="http://www.olegsych.com/2008/04/t4-property-directive/">&lt;#@ property #&gt;</a> appear to be fully supported by the preprocessed templates. The custom directive processors are invoked appropriately and any additional code they produce is merged with the template code in the generated template class. </p>
<h4>References</h4>
<ul>
<li><a title="DSL 2010 Feature Dives- T4 Preprocessing - Part One - Rationale" href="http://blogs.msdn.com/garethj/archive/2008/11/11/dsl-2010-feature-dives-t4-preprocessing-rationale.aspx">DSL 2010 Feature Dives- T4 Preprocessing - Part One - Rationale</a> by Gareth Jones </li>
<li><a title="DSL 2010 Feature Dives- T4 Preprocessing - Part Two - Basic Design" href="http://blogs.msdn.com/garethj/archive/2008/11/12/dsl-2010-feature-dives-t4-preprocessing-part-two-basic-design.aspx">DSL 2010 Feature Dives- T4 Preprocessing - Part Two - Basic Design</a> by Gareth Jones </li>
<li><a title="T4 Preprocessing part 1" href="http://www.clariusconsulting.net/blogs/pga/archive/2009/07/15/160836.aspx">VS10 Beta 1 / T4 Preprocessing part 1</a> by Pablo Galiano </li>
<li><a title="T4 Preprocessing part 2" href="http://www.clariusconsulting.net/blogs/pga/archive/2009/07/15/160853.aspx">VS10 Beta 1 / T4 Preprocessing part 2</a> by Pablo Galiano </li>
<li><a title="Why is a Preprocessed Template the Coolest Thing since Sliced Bread" href="http://blogs.appventure.com/Kathleen/2009/09/04/WhyIsAPreprocessedTemplateTheCoolestThingSinceSlicedBread.aspx">Why is a Preprocessed Template the Coolest Thing since Sliced Bread</a> by Kathleen Dollard </li>
</ul>
<h4>Download</h4>
<ul>
<li><a href="http://www.olegsych.com/wp-content/uploads/2009/09/t4-preprocessed-text-templates-cs.zip">Source code, C#</a> </li>
<li><a href="http://www.olegsych.com/wp-content/uploads/2009/09/t4-preprocessed-text-templates-vb.zip">Source code, Visual Basic</a>&#160; </li>
</ul>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/j-IiMfU0YNk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/feed/</wfw:commentRss>
		</item>
		<item>
		<title>T4 and CodeDOM - Better Together</title>
		<link>http://www.olegsych.com/2009/09/t4-and-codedom-better-together/</link>
		<comments>http://www.olegsych.com/2009/09/t4-and-codedom-better-together/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 19:54:15 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[DSL]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[Visual Basic]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/09/t4-and-codedom-better-together/</guid>
		<description><![CDATA[This article discusses advantages and drawbacks of T4 and CodeDOM and shows how to combine these code generation technologies to get the best of both worlds and allow tool developers to build code generators that can produce code in multiple .NET languages and allow application developers to extend them using templating features of T4 and the programming language of their choice.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> and <a href="http://msdn.microsoft.com/en-us/library/650ax5cx.aspx">CodeDOM</a> are both code generation tools. T4 generates code from a textual template, in essence, using string concatenation. CodeDOM generates code from an object graph where each element represents a common language construct - an if statement, a variable assignment, etc. T4 allows you to put a lot of the output code in template blocks, making the code generator easy to create and customize, but forcing you to create a separate code generator for each output language you need to support. CodeDOM generators are a often verbose and difficult to read, but allow you to generate multiple output languages from a single code generator.</p>
<p>Simplicity and ease of use makes T4 a better code generation tool for <em>application developers</em>, who typically don’t care about generating code in different languages and don’t have time to do it. On the other hand, ability to support multiple output languages makes CodeDOM a better code generation platform for <em>tool developers</em>, who have to support multiple output languages and don’t want to maintain several different code generators that generate the same thing in different languages.</p>
<p>During the past year, we have seen T4 getting adopted by an increasing number of tool developers inside Microsoft, most importantly by the ASP.NET MVC and ADO.NET EF teams. This is great news for application developers, who can now generate their code their way. Or is it? What about tool developers who now have to supply two code generators (T4/C# and T4/VB) instead of one? Actually, make that three code generators - they still have to supply and maintain the original CodeDOM-based generators to support other .NET languages. It is only a matter of time before this added complexity will show its ugly face in the form of quality problems, missing features, missing output languages, etc. In the end, the application developers might just get what they wished for - completely custom code generators that are their to implement and maintain.</p>
<p>Consider the following template from the previous article - <a href="http://www.olegsych.com/2009/08/t4-tutorial-generating-code-from-dsl-models/">Generating Code from DSL Models</a>. This template (ClassTemplate) generates a class declaration based on a definition in a Class Diagram DSL (ModelClass). If you are using <a href="http://t4toolbox.codeplex.com" target="_blank">T4 Toolbox</a>, you have already recognized the base class, <em>Template</em>, which inherits from <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.texttransformation.aspx">TextTranformation</a>. We could have also used pure T4 and have <em>ClassTemplate</em> inherit from <em>TextTransformation</em> directly.</p>
<h6>C#</h6>
<pre class="code"><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">public class ClassTemplate : Template
{
    public ModelClass ModelClass { get; set; }

    public override string TransformText()
    {
</span><span style="background: gold">#&gt;
</span><span style="color: gray">namespace </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> TransformationContext.DefaultNamespace </span><span style="background: gold">#&gt;
</span><span style="color: gray">{
    using System;
    using System.Collections.Generic;

    public class </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> this.ModelClass.Name </span><span style="background: gold">#&gt;
</span><span style="color: red">    </span><span style="color: gray">{
</span><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">        foreach (ModelAttribute attribute in this.ModelClass.Attributes)
        {
</span><span style="background: gold">#&gt;
</span><span style="color: red">        </span><span style="color: gray">public </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> attribute.Type </span><span style="background: gold">#&gt;</span><span style="color: red"> </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> attribute.Name </span><span style="background: gold">#&gt;</span><span style="color: red"> </span><span style="color: gray">{ get; set; }
</span><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">        }
</span><span style="background: gold">#&gt;
</span><span style="color: red">    </span><span style="color: gray">}
}
</span><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">        return this.GenerationEnvironment.ToString();
</span><span style="background: #f0f8ff; color: #191970">    }
}
</span><span style="background: gold">#&gt;</span></pre>
<h6>Visual Basic</h6>
<pre class="code"><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">Public Class ClassTemplate
    Inherits Template

    Public ModelClass As ModelClass

    Public Overrides Function TransformText()
</span><span style="background: gold">#&gt;
</span><span style="color: gray">Imports System
Imports System.Collections.Generic

Namespace </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> TransformationContext.DefaultNamespace </span><span style="background: gold">#&gt;
</span><span style="color: red">    </span><span style="color: gray">Public Class </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> Me.ModelClass.Name </span><span style="background: gold">#&gt;
&lt;#+
</span><span style="background: #f0f8ff; color: #191970">        For Each attribute As ModelAttribute in Me.ModelClass.Attributes
</span><span style="background: gold">#&gt;
</span><span style="color: red">        </span><span style="color: gray">Public </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> attribute.Name </span><span style="background: gold">#&gt;</span><span style="color: red"> </span><span style="color: gray">As </span><span style="background: gold">&lt;#=</span><span style="background: #f0f8ff; color: #191970"> attribute.Type </span><span style="background: gold">#&gt;
&lt;#+
</span><span style="background: #f0f8ff; color: #191970">        Next
</span><span style="background: gold">#&gt;
</span><span style="color: red">    </span><span style="color: gray">End Class
End Namespace
</span><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">        Return Me.GenerationEnvironment.ToString()
</span><span style="background: #f0f8ff; color: #191970">    End Function
End Class
</span><span style="background: gold">#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Keep in mind that this template is simple only because it’s a sample. A real-world code generator that provides actual value, such as the <a href="http://www.olegsych.com/2009/01/t4-toolbox-linq-to-sql-classes-generator/">LINQ to SQL entity class generator</a>, can easily be thousands lines long. As a tool developer on the T4 Toolbox team, I don’t want to translate the LINQ to SQL template from C# to Visual Basic only so that I have to then maintain both. I would prefer to have a single code base to develop and maintain, but as a tool developer, I feel that I should not limit the audience of my tool just to C# developers.</p>
<p>Do we have to choose between the needs of application developers and the needs of tool developers? Is it possible for tool developers to use CodeDOM to develop code generators and for application developers to use T4 to customize and extend them? Well… YES! Thanks for asking!</p>
<h4>How Would That Work?</h4>
<p><em>A Tool developer </em>would implement the <em>ClassTemplate</em> using CodeDOM and encapsulate code that generates individual type members, such as fields or properties, in virtual methods, such as RenderProperty.</p>
<h6>C#</h6>
<pre class="code">

<span style="color: blue">public class </span><span style="color: #2b91af">ClassTemplate </span>: <span style="color: #2b91af">Template
</span>{
  <span style="color: green">// &#8230;</span>
  <span style="color: blue">protected virtual void </span>RenderProperty(<span style="color: #2b91af">ModelAttribute </span>attribute)
  {
    <span style="color: #2b91af">CodeMemberProperty </span>property = <span style="color: blue">new </span><span style="color: #2b91af">CodeMemberProperty</span>();
    property.Attributes = <span style="color: #2b91af">MemberAttributes</span>.Public | <span style="color: #2b91af">MemberAttributes</span>.Final;
    property.Type = <span style="color: blue">new </span><span style="color: #2b91af">CodeTypeReference</span>(attribute.Type);
    property.Name = <span style="color: blue">this</span>.LanguageProvider.CreateEscapedIdentifier(attribute.Name);

    property.GetStatements.Add(
      <span style="color: blue">new </span><span style="color: #2b91af">CodeMethodReturnStatement</span>(
        <span style="color: blue">new </span><span style="color: #2b91af">CodeFieldReferenceExpression</span>(
          <span style="color: blue">new </span><span style="color: #2b91af">CodeThisReferenceExpression</span>(),
          <span style="color: blue">this</span>.FieldName(attribute.Name))));

    property.SetStatements.Add(
      <span style="color: blue">new </span><span style="color: #2b91af">CodeAssignStatement</span>(
        <span style="color: blue">new </span><span style="color: #2b91af">CodeFieldReferenceExpression</span>(
          <span style="color: blue">new </span><span style="color: #2b91af">CodeThisReferenceExpression</span>(),
          <span style="color: blue">this</span>.FieldName(attribute.Name)),
        <span style="color: blue">new </span><span style="color: #2b91af">CodePropertySetValueReferenceExpression</span>()));

    <span style="color: blue">this</span>.LanguageProvider.GenerateCodeFromMember(
      property, <span style="color: blue">this</span>.generationWriter, <span style="color: blue">null</span>);
  }
  <span style="color: green">// &#8230;</span>
}
</pre>
<p>There is no Visual Basic example of this code, because in this case, the tool developer chose to use C# as the programming language.</p>
<p><em>An Application developer </em>would override the virtual method in a T4 template and use text templating instead of CodeDOM. The code below illustrates how the code generating properties could be extended to generate <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx" target="_blank">DataMemberAttribute</a> declarations and make the properties serializable by <a href="http://msdn.microsoft.com/en-us/library/ms735119.aspx" target="_blank">WCF</a>.</p>
<h6>C#</h6>
<pre class="code">

<span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">    class T4ClassTemplate : ClassTemplate
    {
        protected override void RenderProperty(ModelAttribute attribute)
        {
</span><span style="background: gold">#&gt;
</span><span style="color: gray">[DataMember]
</span><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">            base.RenderProperty(attribute);
        }
    }
</span><span style="background: gold">#&gt;</span>
</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code"><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">    Class T4ClassTemplate
        Inherits ClassTemplate

        Protected Overrides Sub RenderProperty(attribute As ModelAttribute)
</span><span style="background: gold">#&gt;
</span><span style="color: gray">&lt;DataMember&gt; _
</span><span style="background: gold">&lt;#+
</span><span style="background: #f0f8ff; color: #191970">            MyBase.RenderProperty(attribute)
        End Sub
    End Class
</span><span style="background: gold">#&gt;</span></pre>
<p>Note that the application developer is using <em>T4 </em>text templating features to extend a code generator written with <em>CodeDOM</em>. She did not have to reimplement the entire code generator in T4, only modify the logic she was interested in changing. In this example, she has extended the logic that generates property code using her language of choice - either Visual Basic or C#.</p>
<h4>What’s the Trick?</h4>
<p>Notice that our <em>RenderProperty </em>method uses <a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.generatecodefrommember.aspx" target="_blank">GenerateCodeFromMember</a> method to convert property declaration from a CodeMemberProperty object to text in the <a href="http://msdn.microsoft.com/en-us/library/Microsoft.VisualStudio.TextTemplating.TextTransformation.GenerationEnvironment.aspx" target="_blank">GenerationEnvironment</a>, a <a href="http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx" target="_blank">StringBuilder</a> object that accumulates output generated by our <em>Template</em>. This is why we can override the <em>RenderProperty </em>method in T4 and use text templating to change the generated code.</p>
<p>The rest of the magic is happening in the <em>TransformText</em> method, which builds the CodeDOM graph of the class we are generating using <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codesnippettypemember.aspx" target="_blank">CodeSnippetTypeMember</a> objects instead of the <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codememberproperty.aspx" target="_blank">CodeMemberProperty</a>, <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codememberfield.aspx" target="_blank">CodeMemberField</a> and <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codemembermethod.aspx" target="_blank">CodeMemberMethod</a> objects we would use normally. The text for the CodeSnippetTypeMember objects is extracted from the GenerationEnvironment.</p>
<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">ClassTemplate </span>: <span style="color: #2b91af">Template
</span>{
  <span style="color: blue">public </span><span style="color: #2b91af">CodeDomProvider </span>LanguageProvider = <span style="color: #2b91af">CodeDomProvider</span>.CreateProvider(<span style="color: #a31515">&quot;CSharp&quot;</span>);
  <span style="color: blue">private </span><span style="color: #2b91af">StringWriter </span>generationWriter;
  <span style="color: blue">private </span><span style="color: #2b91af">CodeGeneratorOptions </span>options;
<span style="color: gray">
  </span><span style="color: blue">public </span><span style="color: #2b91af">ModelClass </span>ModelClass { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

  <span style="color: blue">public </span>ClassTemplate()
  {
    <span style="color: blue">this</span>.generationWriter = <span style="color: blue">new </span><span style="color: #2b91af">StringWriter</span>(<span style="color: blue">this</span>.GenerationEnvironment);
  }
<span style="color: gray">
  </span><span style="color: blue">public override string </span>TransformText()
  {
    <span style="color: #2b91af">CodeNamespace </span>@namespace = <span style="color: blue">new </span><span style="color: #2b91af">CodeNamespace</span>(<span style="color: #2b91af">TransformationContext</span>.DefaultNamespace);
    @namespace.Imports.Add(<span style="color: blue">new </span><span style="color: #2b91af">CodeNamespaceImport</span>(<span style="color: #a31515">&quot;System&quot;</span>));
    @namespace.Imports.Add(<span style="color: blue">new </span><span style="color: #2b91af">CodeNamespaceImport</span>(<span style="color: #a31515">&quot;System.Collections.Generic&quot;</span>));

    <span style="color: #2b91af">CodeTypeDeclaration </span>@class = <span style="color: blue">new </span><span style="color: #2b91af">CodeTypeDeclaration</span>(<span style="color: blue">this</span>.ModelClass.Name);
    @class.TypeAttributes = <span style="color: #2b91af">TypeAttributes</span>.Public;
    @namespace.Types.Add(@class);

    <span style="color: blue">foreach </span>(<span style="color: #2b91af">ModelAttribute </span>attribute <span style="color: blue">in this</span>.ModelClass.Attributes)
    {
       <span style="color: blue">this</span>.RenderField(attribute);
       @class.Members.Add(<span style="color: blue">new </span><span style="color: #2b91af">CodeSnippetTypeMember</span>(<span style="color: blue">this</span>.GenerationEnvironment.ToString()));
       <span style="color: blue">this</span>.GenerationEnvironment.Length = 0;
    }

    <span style="color: blue">foreach </span>(<span style="color: #2b91af">ModelAttribute </span>attribute <span style="color: blue">in this</span>.ModelClass.Attributes)
    {
      <span style="color: blue">this</span>.RenderProperty(attribute);
      @class.Members.Add(<span style="color: blue">new </span><span style="color: #2b91af">CodeSnippetTypeMember</span>(<span style="color: blue">this</span>.GenerationEnvironment.ToString()));
      <span style="color: blue">this</span>.GenerationEnvironment.Length = 0;
    }

    <span style="color: blue">this</span>.LanguageProvider.GenerateCodeFromNamespace(@namespace, <span style="color: blue">this</span>.generationWriter, <span style="color: blue">null</span>);
    <span style="color: blue">return this</span>.GenerationEnvironment.ToString();
  }
}

</pre>
<p>In other words, to generate a particular type member, such as property, we a) build it as a CodeDOM graph; b) convert it to text stored in GenerationEnvironment of the Template; c) extract text from GenerationEnvironment and wrap it in a CodeSnippetTypeMember object; and d) finish building the CodeDOM graph of the type using code snippet objects. Because steps a) and b) occur in a virtual method, we can override it using pure text templating functionality of T4.</p>
<h4>What’s the Catch?</h4>
<p>Unfortunately, CodeDOM does not provide code snippet descendants for all types. In particular, there is no CodeSnippetTypeDeclaration descendant for <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codetypedeclaration.aspx" target="_blank">CodeTypeDeclaration</a>. Therefore, it is not possible to extract generation of the class declaration from the <em>TransformText </em>method into a virtual method similar to <em>RenderProperty</em> that it could be overridden using T4. Specifically, it would not be possible to extend the code generator in this example and use T4 text templating to generate <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank">DataContractAttribute</a> declaration for the class. We can provide an event or a virtual method in <em>ClassTemplate </em>that would allow <em>T4ClassTemplate</em> to access and modify the <em>CodeTypeDeclaration </em>before the output code is generated from it, however <em>T4ClassTemplate</em> would need to manipulate it in the CodeDOM form. It is very much possible to do in T4 code, but would not be as easy as using the text templating.</p>
<h4>So What Are You Saying?</h4>
<p>As long as a CodeDOM-based generator provides adequate extensibility points, such as virtual methods and/or events, the application developers can extend or replace parts of its logic in T4 without having to reimplement or maintain the entire generator. Although this approach is significantly more complex than creating a T4-based code generator for a single output language, it is comparable in size and complexity to having multiple T4-based generators, producing the same code in different output languages. As the size and complexity of the generated code grows, maintaining several T4-based generators in different .NET languages becomes more complex than maintaining a single CodeDOM-based generator. This approach is a compromise between the needs of application developers, who want to customize generated code using T4 and their language of choice, and tool developers, who want to maintain a single code base.</p>
<h4>Download</h4>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/09/classcodedom.zip">Source code, C# and Visual Basic</a>. Follow instructions in the <a href="http://www.olegsych.com/2009/08/t4-tutorial-generating-code-from-dsl-models/">previous article</a> to compile and run it.</p>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/XWqm4WZGpHQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/09/t4-and-codedom-better-together/feed/</wfw:commentRss>
		</item>
		<item>
		<title>T4 Tutorial: Generating Code from DSL Models</title>
		<link>http://www.olegsych.com/2009/08/t4-tutorial-generating-code-from-dsl-models/</link>
		<comments>http://www.olegsych.com/2009/08/t4-tutorial-generating-code-from-dsl-models/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 11:50:16 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/08/t4-tutorial-generating-code-from-dsl-models/</guid>
		<description><![CDATA[This article provides an overview of Domain-Specific Languages in Visual Studio SDK and demonstrates how to use T4 Toolbox to make DSL code generators easier to use, maintain and extend.]]></description>
			<content:encoded><![CDATA[<p>This post is a part of the series that introduces code generation with <a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx">Text Templates</a> (also known as <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/" target="_blank">T4</a> Templates) in Visual Studio using C# and Visual Basic; explains how to create reusable templates and combine them in complex code generators. In order to follow examples in this article, you need to have Visual Studio 2008 SP1 Standard Edition or higher, <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=59EC6EC3-4273-48A3-BA25-DC925A45584D&amp;displaylang=en" target="_blank">Visual Studio 2008 SDK 1.1</a>, <a href="http://www.codeplex.com/t4toolbox">T4 Toolbox</a> and <a href="http://www.olegsych.com/2009/04/t4-editor-by-tangible-engineering">T4 Editor</a> installed on your computer.</p>
<h4>Domain-Specific Language Tools</h4>
<p>As the name implies, a Domain-Specific Language (DSL) is a programming language dedicated to a particular problem domain. Although we usually associate the term <em>programming language</em> with a textual language, such as C# and Visual Basic, DSLs also take a form of graphical modeling languages, such as UML diagrams, or Excel spreadsheets. Visual Studio SDK includes <a href="http://msdn.microsoft.com/en-us/library/bb126235.aspx" target="_blank">Domain-Specific Language Tools</a>, which allow you to build DSLs of the graphical variety. Shown below, is a Class Designer built using DSL tools and included as a sample in the Visual Studio SDK.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Class Designer" border="0" alt="Class Designer" src="http://www.olegsych.com/wp-content/uploads/2009/08/image.png" width="580" height="360" /></p>
<p>This sample DSL allows you to model a set of classes in a graphical design environment, similar to a UML diagrams in Visio. The model it creates is stored in XML format.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.olegsych.com/wp-content/uploads/2009/08/image1.png" width="580" height="348" /> </p>
<p>The Class Designer example also includes T4 templates that you can use as a starting point to generate code from this model. These T4 templates rely on a <a href="http://www.olegsych.com/2008/05/t4-architecture/" target="_blank">custom directive processor</a> called <em>ClassDiagrams </em>to make the model data available for code generation. The directive processor ensures that metadata assembly is referenced when the template is compiled and generates a special property called <em>ModelRoot</em> which provides access to the metadata loaded from the model file - <em>Sample.classes</em>. </p>
<h6>C#</h6>
<p> <a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>
<pre class="code"><span style="color: black">&lt;#
</span><span style="color: green">/***************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    This code is licensed under the Visual Studio SDK license terms.

    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

***************************************************************************/
</span><span style="color: black">#&gt;
&lt;#@ </span><span style="color: brown">template </span><span style="color: red">inherits</span><span style="color: black">=&quot;</span><span style="color: blue">ModelingTextTransformation</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">output </span><span style="color: red">extension</span><span style="color: black">=&quot;</span><span style="color: blue">.txt</span><span style="color: black">&quot; #&gt;
&lt;#@ ClassDiagrams </span><span style="color: red">processor</span><span style="color: black">=&quot;</span><span style="color: blue">ClassDiagramsDirectiveProcessor</span><span style="color: black">&quot;
  </span><span style="color: red">requires</span><span style="color: black">=&quot;</span><span style="color: blue">fileName=&#8217;Sample.classes&#8217;</span><span style="color: black">&quot;  #&gt;

Report template

&lt;#= </span><span style="color: blue">this</span><span style="color: black">.ModelRoot.Name #&gt;

&lt;#
  </span><span style="color: green">// When you change the DSL Definition, some of the code below may not work.

  </span><span style="color: blue">foreach </span><span style="color: black">(ModelType type </span><span style="color: blue">in this</span><span style="color: black">.ModelRoot.Types)
  {
#&gt;
    &lt;#= type.GetType().Name #&gt; &lt;#= type.Name #&gt;
&lt;#
  }
#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code"><span style="color: black">&lt;#
</span><span style="color: green">REM    Copyright (c) Microsoft Corporation. All rights reserved.
REM    This code is licensed under the Visual Studio SDK license terms.
REM
REM    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
REM    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
REM    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
REM    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
</span><span style="color: black">#&gt;
&lt;#@ </span><span style="color: brown">template </span><span style="color: red">inherits</span><span style="color: black">=&quot;</span><span style="color: blue">ModelingTextTransformation</span><span style="color: black">&quot;</span><span style="color: red">language</span><span style="color: black">=&quot;</span><span style="color: blue">VB</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">output </span><span style="color: red">extension</span><span style="color: black">=&quot;</span><span style="color: blue">.txt</span><span style="color: black">&quot; #&gt;
&lt;#@ ClassDiagrams </span><span style="color: red">processor</span><span style="color: black">=&quot;</span><span style="color: blue">ClassDiagramsDirectiveProcessor</span><span style="color: black">&quot;
  </span><span style="color: red">requires</span><span style="color: black">=&quot;</span><span style="color: blue">fileName=&#8217;Sample.classes&#8217;</span><span style="color: black">&quot;  #&gt;

Report template

&lt;#= </span><span style="color: blue">Me</span><span style="color: black">.ModelRoot.Name #&gt;

&lt;#
  </span><span style="color: green">REM When you change the DSL Definition, some of the code below may not work.

  </span><span style="color: blue">For Each </span><span style="color: black">type </span><span style="color: blue">As </span><span style="color: black">ModelType </span><span style="color: blue">In Me</span><span style="color: black">.ModelRoot.Types
#&gt;
    &lt;#= type.GetType().Name #&gt; &lt;#= type.Name #&gt;
&lt;#
  </span><span style="color: blue">Next
</span><span style="color: black">#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>The output produced by these templates is shown below. In a real-world scenario, you would probably generate something more useful, such as C# or Visual Basic class declarations or, perhaps, SQL table scripts. </p>
<pre class="code">Report template

T4Toolbox.Examples.OrderEntry

    ModelClass Customer
    ModelClass Address
    ModelClass Product
    ModelClass Supplier
    ModelClass Order</pre>
</p>
<p>Because the DSL samples in Visual Studio SDK use standard T4 templates, they can only produce a single output file per template. As a result, you are either limited to generating all artifacts in a single large file, or having multiple templates to generate smaller files. Luckily, <a href="http://t4toolbox.codeplex.com" target="_blank">T4 Toolbox</a> can be used to generate multiple files from DSL models as we will see later in this article. </p>
<h4>Domain-Specific Language Implementation</h4>
<p>Before we take a closer look at generating code, we will review some of the basics you will need to understand in order to follow discussion of code generation. For complete details, please refer to the <a href="http://msdn.microsoft.com/en-us/library/bb126235.aspx" target="_blank">Visual Studio SDK</a> and <a href="http://www.amazon.com/dp/0321398203?tag=domaispecidev-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321398203&amp;adid=0G39ZVCDSDYJQ1NJP1Y4&amp;" target="_blank">Domain-Specific Development with Visual Studio DSL Tools</a> written <a href="http://blogs.msdn.com/GarethJ" target="_blank">Gareth Jones</a> and other people who lead creation of this technology at Microsoft. </p>
<p>The best way to follow this discussion is by opening the ClassDiagrams example from Visual Studio SDK.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.olegsych.com/wp-content/uploads/2009/08/image2.png" width="580" height="452" /> </p>
<p>The Class Designer DSL itself is also defined by a DSL model. The screenshot below shows a fragment of its definition located in the <em>DslDefinition.dsl</em> file inside of the <em>Dsl </em>project.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.olegsych.com/wp-content/uploads/2009/08/image3.png" width="580" height="438" /> </p>
<p>The diagramming notation is similar enough to UML class diagrams for you to be able to interpret it without reading a book on DSLs. As you can see, the sample DSL has a <em>ModelRoot</em> that contains a collection called <em>Types</em> of <em>ModelType </em>objects. <em>ModelClass</em> inherits from <em>ModelType</em> and stores information about a single class, including its collections of <em>Attributes</em> and <em>Operations</em>. In addition to the domain types, <em><img style="border-right-width: 0px; margin: 5px 0px 0px 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Class Diagrams Sample Solution" border="0" alt="Class Diagrams Sample Solution" align="right" src="http://www.olegsych.com/wp-content/uploads/2009/08/image4.png" width="240" height="239" /></em>like <em>ModelRoot</em> and <em>ModelClass</em>, the DSL definition also includes diagram elements, such as <em>ClassShape</em> and <em>AssociationConnector</em>, which are not shown here.</p>
<p>The <em>Dsl</em> project contains most of the code required to implement the DSL itself and its design environment in Visual Studio. The <em>GeneratedCode</em> folder contains a set of T4 templates that generate most of the required code. In particular, it generates strongly-typed .NET code for accessing the resulting DSL models programmatically. Here is the template called <em>DomainClasses.tt</em> that generates metadata classes for the sample Class DSL.</p>
<p><a href="http://11011.net/software/vspaste"></a></p>
<pre class="code"><span style="color: black">&lt;#
</span><span style="color: green">/***************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    This code is licensed under the Visual Studio SDK license terms.

    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

***************************************************************************/
</span><span style="color: black">#&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">Dsl\DomainClassCodeGenerator.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ Dsl </span><span style="color: red">processor</span><span style="color: black">=&quot;</span><span style="color: blue">DslDirectiveProcessor</span><span style="color: black">&quot;
  </span><span style="color: red">requires</span><span style="color: black">=&quot;</span><span style="color: blue">fileName=&#8217;..\DslDefinition.dsl&#8217;</span><span style="color: black">&quot; #&gt;</span></pre>
<p>The screenshot below shows an extract from the code this template produces. The <em>ModelClass </em>shown in it is generated from the <em>ModelClass</em> element defined in the sample Class DSL diagram above. An instance of the <em>ModelClass</em> represents a particular class defined in the class model, such as <em>Customer </em>or <em>Product</em> shown in the beginning of this article. </p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.olegsych.com/wp-content/uploads/2009/08/image5.png" width="580" height="376" /></p>
<p><em>ModelRoot</em>, <em>ModelType</em>, <em>ModelClass</em>, <em>ModelAttribute </em>and other classes in this file are what our code generator will use to access model definition created by the Class Designer.</p>
</p>
<h4>Generating Code From DSL Models</h4>
</p>
<p>For our DSL code generator, we will use the standard T4 Toolbox design pattern based on <a href="http://www.olegsych.com/2008/09/t4-tutorial-creating-reusable-code-generation-templates/" target="_blank">Template</a> and <a href="http://www.olegsych.com/2008/09/t4-tutorial-creating-complex-code-generators/" target="_blank">Generator</a> classes. </p>
<h6>C#</h6>
<pre class="code">

<span style="color: black">&lt;#@ </span><span style="color: brown">template </span><span style="color: red">language</span><span style="color: black">=&quot;</span><span style="color: blue">C#v3.5</span><span style="color: black">&quot; </span><span style="color: red">hostspecific</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; </span><span style="color: red">debug</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; </span>

<span style="color: black">    </span><span style="color: red">inherits</span><span style="color: black">=&quot;</span><span style="color: blue">ModelingTextTransformation</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">output </span><span style="color: red">extension</span><span style="color: black">=&quot;</span><span style="color: blue">txt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">T4Toolbox.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">ClassGeneratorCS.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">ClassTemplateCS.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ ClassDiagrams </span><span style="color: red">processor</span><span style="color: black">=&quot;</span><span style="color: blue">ClassDiagramsDirectiveProcessor</span><span style="color: black">&quot; </span>

<span style="color: black">    </span><span style="color: red">requires</span><span style="color: black">=&quot;</span><span style="color: blue">fileName=&#8217;Sample.classes&#8217;</span><span style="color: black">&quot;  #&gt;
&lt;#
</span><span style="color: green">    </span><span style="color: black">ClassGenerator generator = </span><span style="color: blue">new </span><span style="color: black">ClassGenerator();
    generator.ModelRoot = <font color="#0000ff">this</font>.ModelRoot;
    generator.Run();
#&gt;</span>
</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code">

<span style="color: black">&lt;#@ </span><span style="color: brown">template </span><span style="color: red">language</span><span style="color: black">=&quot;</span><span style="color: blue">VBv3.5</span><span style="color: black">&quot; </span><span style="color: red">hostspecific</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; </span><span style="color: red">debug</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; </span>

<span style="color: black">    </span><span style="color: red">inherits</span><span style="color: black">=&quot;</span><span style="color: blue">ModelingTextTransformation</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">output </span><span style="color: red">extension</span><span style="color: black">=&quot;</span><span style="color: blue">txt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">T4Toolbox.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">ClassGeneratorVb.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">ClassTemplateVb.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ ClassDiagrams </span><span style="color: red">processor</span><span style="color: black">=&quot;</span><span style="color: blue">ClassDiagramsDirectiveProcessor</span><span style="color: black">&quot; </span>

<span style="color: black">    </span><span style="color: red">requires</span><span style="color: black">=&quot;</span><span style="color: blue">fileName=&#8217;Sample.classes&#8217;</span><span style="color: black">&quot;  #&gt;
&lt;#
</span><span style="color: green">    </span><span style="color: blue">Dim </span><span style="color: black">generator </span><span style="color: blue">As </span><span style="color: black">ClassGenerator = </span><span style="color: blue">New </span><span style="color: black">ClassGenerator()
    generator.ModelRoot = <font color="#0000ff">Me</font></span><span style="color: black">.ModelRoot
    generator.Run()
#&gt;</span>
</pre>
<p>The sample generator consists of two separate classes. <em>ClassTemplate</em>, defined in <em>ClassTemplateCs.tt</em> or <em>ClassTemplateVb.tt</em>, takes <em>ModelClass</em> and generates a class declaration. <em>ClassGenerator</em>, defined in <em>ClassGeneratorCs.tt</em> or <em>ClassGeneratorVb.tt</em>, takes <em>ModelRoot</em> as a parameter, iterates through its list of <em>Types</em> and renders <em>ClassTemplate</em> for each <em>ModelClass</em> it finds. There is nothing special about design or implementation of <em>ClassTemplate</em> and <em>ClassGenerator</em>, except for the <em>ModelClass</em> and <em>ModelRoot</em> types they use as parameters for code generation. These types are provided by the Class Diagrams DSL. </p>
<p>This code generator produces class declarations for types defined in <em>Sample.classes </em>in separate source files.</p>
<h6>C#</h6>
<pre class="code"><span style="color: blue">namespace </span>T4ToolboxDslCs
{
    <span style="color: blue">using </span>System;
    <span style="color: blue">using </span>System.Collections.Generic;

    <span style="color: blue">public class </span><span style="color: #2b91af">Address
    </span>{
        <span style="color: blue">public </span><span style="color: #2b91af">String </span>Street { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
        <span style="color: blue">public </span><span style="color: #2b91af">String </span>City { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
        <span style="color: blue">public </span><span style="color: #2b91af">String </span>State { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
        <span style="color: blue">public </span><span style="color: #2b91af">String </span>Zip { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Visual Basic</h6>
<pre class="code"><span style="color: blue">Imports </span>System
<span style="color: blue">Imports </span>System.Collections.Generic

<span style="color: blue">Namespace </span>T4ToolboxDsl
    <span style="color: blue">Public Class </span>Address
        <span style="color: blue">Public </span>Street <span style="color: blue">As String
        Public </span>City <span style="color: blue">As String
        Public </span>State <span style="color: blue">As String
        Public </span>Zip <span style="color: blue">As String
    End Class
End Namespace</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>The main code generation file, SampleCs.tt or SampleVb.tt depending on your language preference, does have several important differences from a typical T4 Toolbox template. <strong>First</strong> important difference is the &lt;#@ ClassDiagrams #&gt; custom directive placed in the beginning of the template. This custom directive has a <em>requires</em> parameter that expects a value in form <em>fileName=’&lt;FilePath&gt;’</em>, where &lt;FilePath&gt; is a relative path to the DSL model file. The <em>ClassDiagrams</em> directive processor is provided by the Class Diagrams DSL and registered in the experimental registry hive of Visual Studio when you run the <em>Dsl</em> project in the Visual Studio SDK sample. Once the DSL is deployed this directive processor would be registered under standard Visual Studio registry hive. </p>
<pre class="code">[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0Exp\Configuration\TextTemplating\DirectiveProcessors\ClassDiagramsDirectiveProcessor]
@=&quot;A directive processor that provides access to ClassDiagrams files&quot;
&quot;Class&quot;=&quot;Microsoft.Example.ClassDiagrams.ClassDiagramsDirectiveProcessor&quot;
&quot;CodeBase&quot;=&quot;file:///C:/Users/you/Desktop/DslPackage/bin/Debug/Microsoft.Example.ClassDiagrams.Dsl.DLL&quot;</pre>
<p><strong>Second</strong> important difference is the use of <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.vshost.modelingtexttransformation.aspx" target="_blank">ModelingTextTransformation</a> in the inherits parameter of the <a href="http://www.olegsych.com/2008/02/t4-template-directive/">template directive</a>. This base class provides additional methods, such as <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.vshost.modelingtexttransformation.adddomainmodel.aspx" target="_blank">AddDomainModel</a> and <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.vshost.modelingtexttransformation.convertmodelrelativepathtotemplaterelativepath.aspx" target="_blank">ConvertModelRelativePathToTemplateRelativePath</a>, which are required for the code generated by the <em>ClassDiagrams </em>directive processor to be compiled correctly during template transformation.</p>
<h4>Running Sample Source Code</h4>
<p><img style="border-right-width: 0px; margin: 0px 5px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Debugging Sample Solution" border="0" alt="Debugging Sample Solution" align="left" src="http://www.olegsych.com/wp-content/uploads/2009/08/image6.png" width="200" height="275" />Complete source code is available for download in the end this article. It is based on the ClassDiagrams sample from Visual Studio SDK. In order to see the code generation in action, you will need to start debugging the <em>Dsl</em> project in <em>Example.ClassDiagrams </em>solution. </p>
<p>This will start a second instance of Visual Studio in the experimental hive and load <em>Debugging </em>solution. This solution contains several projects. <em>Debugging</em> project came in Visual Studio SDK with this sample and contains standard T4 templates shown at the beginning of this article. </p>
<p><em>T4ToolboxDslCs </em>and <em>T4ToolboxDslVb</em> are the C# and Visual Basic projects that contain code generators based on the T4 Toolbox. <em>SampleCs.tt</em> and <em>SampleVb.tt</em> are the actual code generators that produce class declarations in separate source files. Remember that you need to click the <em>Show All Files </em>button in the toolbar of <em>Solution Explorer </em>in order to see the output files in Visual Basic projects.</p>
<h4>Conclusion</h4>
<p>Graphical Domain-Specific Languages are a very powerful tool that can be used to build complete solutions for modeling and generating code for complex problem domains. DSLs are typically developed by Microsoft and other companies who specialize in building development tools. Due to inherent complexity of designing a graphical language and implementing a complete modeling environment integrated in Visual Studio IDE,&#160; DSL development is not feasible in scope of a typical <em>application </em>development project. The investment required to implement and support a viable DSL can only be recouped on some of the largest application development projects that involve dozens of people and last for several years. </p>
<p>These larger projects, where DSL development is justified, typically require generating large volumes of code. Due to the T4 limitation of generating a single output file per template, developers are forced to generate multiple classes in each output file and use multiple template files to generate code from a single model to keep the size of output files manageable. A great example of this problem is the implementation of a DSL itself, which has a single model definition file and multiple code generation templates files. Each of the generated files contains numerous class definitions, making them difficult to read and debug. </p>
<p>The traditional T4 templates are also impossible to extend without resorting to modifying their source code directly. On a large application development project, the team <em>developing </em>the DSL quickly becomes a bottleneck for customization requests. Alternatively, the teams <em>using </em>the DSL start customizing the main T4 templates which requires additional effort to maintain them over time as new versions of the DSL are released. </p>
<p>Although the issues around template extensibility and output file management not be difficult for <em>authors </em>of the DSL, the large number and size of the T4 templates required for non-trivial scenarios present a serious challenge for application developers using it. T4 Toolbox can help you address these problems. By implementing your DSL code generator as a set of Template and Generator classes as shown in this article, you can generate all required output files from a single T4 file and allow developers to extend it with the help of inheritance and encapsulation instead of modifying the main code generator directly. </p>
<h4>Download</h4>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/08/classdiagramsdsl.zip" target="_blank">Source Code, C# and Visual Basic</a></p>
<h4>Resources</h4>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/bb126235.aspx" target="_blank">Domain-Specific Language Tools</a></li>
<li><a href="http://www.amazon.com/dp/0321398203?tag=domaispecidev-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321398203&amp;adid=0G39ZVCDSDYJQ1NJP1Y4&amp;" target="_blank">Domain-Specific Development with Visual Studio DSL Tools</a></li>
<li><a href="http://www.olegsych.com/2008/09/t4-tutorial-creating-reusable-code-generation-templates/" target="_blank">Creating reusable code generation templates</a></li>
<li><a href="http://www.olegsych.com/2008/09/t4-tutorial-creating-complex-code-generators/" target="_blank">Creating complex code generators</a></li>
<li><a href="http://www.olegsych.com/2009/02/t4-tutorial-making-code-generators-extensible/" target="_blank">Making code generators extensible</a></li>
<li><a href="http://www.olegsych.com/2008/10/t4-tutorial-reusing-code-generators-on-multiple-projects/" target="_blank">Reusing code generators on multiple projects</a></li>
</ul>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/BWBr-qkvPtk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/08/t4-tutorial-generating-code-from-dsl-models/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Customizing TFS Process Guidance</title>
		<link>http://www.olegsych.com/2009/07/customizing-tfs-process-guidance/</link>
		<comments>http://www.olegsych.com/2009/07/customizing-tfs-process-guidance/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 18:35:13 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[Tools]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[TFS]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<category><![CDATA[VSTS]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/07/customizing-tfs-process-guidance/</guid>
		<description><![CDATA[This article provides an overview of customizing process guidance for Visual Studio Team Foundation Server.]]></description>
			<content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/teamsystem/dd408382.aspx" target="_blank">Team Foundation Server</a> (TFS) is the core of <a href="http://msdn.microsoft.com/teamsystem" target="_blank">Visual Studio Team System</a> (VSTS), an <a href="http://www.davidchappell.com/WhatIsALM--Chappell.pdf" target="_blank">Application Lifecycle Management</a> (ALM) platform from Microsoft. TFS offers integrated team portal, version control, work-item tracking, build management, process guidance and business intelligence functionality. TFS provides interactive online documentation based on <a href="http://www.microsoft.com/downloads/details.aspx?familyid=A71AC896-1D28-45A4-880C-8B0CC8265C63&amp;displaylang=en" target="_blank">Microsoft Solutions Framework</a> (MSF), a proven methodology for planning, designing, implementing and deploying information systems and solutions. </p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="MSF for Agile Software Development" border="0" alt="MSF for Agile Software Development" src="http://www.olegsych.com/wp-content/uploads/2009/07/image33.png" width="580" height="431" /> </p>
<p>Out of the box, TFS 2008 comes with two varieties of process guidance: <a href="http://www.microsoft.com/downloads/details.aspx?familyid=EA75784E-3A3F-48FB-824E-828BF593C34D&amp;displaylang=en" target="_blank">MSF for Agile Software Development</a> and <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=12A8D806-BB98-4EB4-BF6B-FB5B266171EB&amp;amp;displaylang=en&amp;displaylang=en" target="_blank">MSF for CMMI Process Improvement</a>. MSF Agile process was designed for smaller teams and teams that use <a href="http://www.agilemanifesto.org" target="_blank">agile development practices</a>, while MSF CMMI process was designed for larger organizations, particularly those using CMMI (<a href="http://www.sei.cmu.edu/cmmi/general/index.html" target="_blank">Capability Maturity Model Integration</a>) approach, teams that require a higher degree of control and visibility over their projects. </p>
<p>You can learn more about MSF Agile and MSF CMMI by reading the process guidance that comes with TFS. If you don’t have access to a TFS project with the process flavor you are interested in, you can download it from MSDN using the links below. Simply open <em>ProcessGuidance.html</em> located in the <em>Windows SharePoint Services\Process Guidance </em>folder in the location where you extracted the project template files.</p>
<h4>MSF Process Guidance is Only a Template</h4>
<p>While MSF Agile and MSF CMMI templates can serve as good starting points for many organizations, there is rarely a perfect fit. The Agile template fits well most of the small- to mid-size IT organizations, however it uses terminology that is too specific to agile software development. Its term <em>Scenario</em> represents what is commonly referred as <em>Service Request</em> or <em>Change Request</em>; the term <em>Bug</em> refers to what is commonly known as <em>Trouble Ticket</em> or <em>Defect Report. </em>The CMMI template uses more appropriate terminology, but due to the large number of work-item types and roles, it is simply an overkill for most organizations. </p>
<p>Today, a typical MIS department usually has a small number of roles (such as Business Analyst, Project Manager, Developer, Database Administrator, Help Desk Technician) established and follows an existing process for managing the change requests and trouble tickets. This process may be based on paper or electronic forms, it may not be perfect, but it is already working. When this organization adopts TFS to improve their process, should they go ahead and adopt MSF Agile or MSF CMMI? </p>
<p>Adopting a new process approach (what you do) at the same time as adopting a new process management tool (how you do it) is a risky proposition. People are creatures of habit and require time to change either the process they follow or the tools they use. Imagine if all cars in a country had to be changed to use voice control instead of traditional steering (change what you do) <em>and</em> that people had to speak to their cars in <a href="http://en.wikipedia.org/wiki/Esperanto" target="_blank">Esperanto</a> (change how you do it). In the resulting chaos, we can be certain that both the congressman who proposed this <em>improvement</em> and the president who didn’t veto the proposal will not be as popular anymore.</p>
<p>When adopting TFS, unless your IT organization is following the MSF Agile&#160; or the MSF CMMI process to the letter, it is much safer to start by customizing the TFS process to match your own. Once your organization is comfortable using TFS as the new process management tool, you can begin adjusting the process itself using TFS. Microsoft provided extensive documentation (see links below) on how to customize the workflows, work items, reports and other features of TFS. However, customization of the <em>process guidance</em> received relatively little attention. Yet in the process of adopting TFS, providing matching guidance for a customized process is very important to ensure the overall success. Outdated guidance will cause confusion, mistakes, delays and frustration for the MIS department and its business partners. So how do we change it?</p>
<h4>VSTS Process Guidance Generator</h4>
<p>Microsoft used the <a href="http://process.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=5626" target="_blank">Guidance Generator</a> to produce MSF Agile and MSF CMMI guidance for TFS 2008. This tool replaced <a href="http://process.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=5234" target="_blank">MSFWinBuild</a> which was used to produce the guidance in TFS 2005. Unlike its predecessor, it uses plain XML file to define contents of the guidance and <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> templates to generate the actual collection of HTML files, included in TFS project templates as process guidance. The remainder of this article will show a typical set of steps you would need to perform to customize guidance for your TFS project.</p>
<h5>Installing Guidance Generator</h5>
<ul>
<li><a href="http://www.olegsych.com/wp-content/uploads/2009/07/image24.png" target="_blank"><img style="border-right-width: 0px; margin: 0px 0px 0px 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Guidance Generator Archive Properties" border="0" alt="Guidance Generator Archive Properties" align="right" src="http://www.olegsych.com/wp-content/uploads/2009/07/image-thumb1.png" width="176" height="240" /></a>Download latest version of the Guidance Generator (2.0.2.1 at the time of this writing) to your local hard drive. </li>
<li>Unblock the ZIP archive you downloaded as shown on the right. This will ensure that the application will not run into any unexpected security errors. </li>
<li>Extract files from the unblocked archive to your hard drive. </li>
</ul>
<p>If you are running a 64-bit version of windows, you will need to use the <a href="http://msdn.microsoft.com/en-us/library/ms164699.aspx" target="_blank">CorFlags</a> command line tool to make sure that the generator runs in 32-bit mode. This will help you to avoid errors that occur when the generator attempts to load 32-bit-only assemblies it requires. </p>
<ul>
<li>Use Command Prompt window to execute the following command in the bin\bin sub-folder at the location you extracted the files. </li>
</ul>
<pre class="code">C:\GuidanceGenerator\bin\bin&gt;corflags TextTemplatingMultiprocessor.exe /32BIT+
Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  3.5.21022.8
Copyright (c) Microsoft Corporation.  All rights reserved.

C:\GuidanceGenerator\bin\bin&gt;</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h5><a href="http://www.olegsych.com/wp-content/uploads/2009/07/image25.png"><img style="border-right-width: 0px; margin: 0px 0px 0px 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Guidance Generator, Extracted Files" border="0" alt="Guidance Generator, Extracted Files" align="right" src="http://www.olegsych.com/wp-content/uploads/2009/07/image-thumb2.png" width="234" height="240" /></a>Building Process Guidance</h5>
<p>Once you have the Guidance Generator installed, your first task is to pick a template (Agile or CMMI) that you will be using as a starting point in your customization. If you are customizing guidance for an existing TFS project, you will want to minimize the amount of editing, so pick the template that matches matches your project.</p>
<ul>
<li>Double-click the <em>Run Tool.cmd</em> file in root folder at the location you extracted the files to start the generator.&#160;&#160;&#160; </li>
<li>In the <em>TemplateProcessor</em> window, enter the following parameter values.
<p><em>Source DSL File:&#160;&#160;&#160;&#160;&#160; </em><strong>agile-guidance.guidance</strong> </p>
<p><em>Template Directory: </em><strong>HTML_Templates</strong> </p>
<p><em>Target Directory:&#160;&#160;&#160;&#160;&#160;&#160; </em><strong>agile-Generated\Process Guidance\Supporting Files</strong> </li>
</ul>
<p>The source file provides content of the guidance. In this example, we are generating process guidance from the source file called <em>agile-guidance.guidance </em>to the output directory called <em>agile-Generated</em>. To generate CMMI guidance, we would need to change these values to <em>cmmi-guidance.guidance</em> and <em>cmmi-Generated </em>respectively.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Guidance Generator, Application" border="0" alt="Guidance Generator, Application" src="http://www.olegsych.com/wp-content/uploads/2009/07/image26.png" width="580" height="333" /></p>
<ul>
<li>Click the <em>Go </em>button. </li>
</ul>
<p>The generator runs for a while and you should see the a log displayed in its output window with information about the number of files that were generated. Once you see “Done”, you can open the generated guidance by double-clicking the <em>ProcessGuidance.html</em> located in the <em>agile-Generated\Process Guidance</em> folder. The actual output files are generated in the <em>agile-Generated\Process Guidance\Supporting Files</em> folder.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Generated Guidance Files" border="0" alt="Generated Guidance Files" src="http://www.olegsych.com/wp-content/uploads/2009/07/image27.png" width="580" height="418" /> </p>
<h5>Customizing Guidance Content</h5>
<p>The guidance content is located in the <em>.guidance</em> files - <em>agile-guidance.guidance </em>and <em>cmmi-guidance.guidance</em>. These are rather large XML files that define topics describing team member roles, work streams, activities, work products, work items, reports, glossary entries and more. </p>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/07/image61.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Agile Guidance Source File" border="0" alt="Agile Guidance Source File" src="http://www.olegsych.com/wp-content/uploads/2009/07/image61-thumb.png" width="580" height="272" /></a></p>
<p>Limited information about the structure of this file can be found in the <em>UserGuide - Guidance Generator.pdf</em> located in the root folder where you extracted the Guidance Generator files downloaded from <a href="http://www.codeplex.com/">CodePlex</a>. This information is by no means complete nor, due to its volume, would not be practical to describe in a single article. In one sentence, this structure can be summarized as this. There is a one-to-one relationship between the major xml elements and the generated HTML files, for example, <em>BusinessAnalyst.htm </em>file is generated from the XML element <em>&lt;Role Key=”BusinessAnalyst”&gt;</em>. If you want to change content for particular HTML file, find the XML element with matching <em>Key</em> and change its contents.</p>
<h6>Source XML</h6>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Business Analyst, XML Definition" border="0" alt="Business Analyst, XML Definition" src="http://www.olegsych.com/wp-content/uploads/2009/07/image68.png" width="580" height="495" /> </p>
<h6>Generated Output</h6>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Business Analyst, Generated HTML" border="0" alt="Business Analyst, Generated HTML" src="http://www.olegsych.com/wp-content/uploads/2009/07/image73.png" width="580" height="530" /> </p>
<p>Editing such a large and complex XML file is challenging. It was not meant to be edited by hand and the internal tool Microsoft created for editing it was not released to public. You may be tempted to use the XML schema file, <em>GuidanceModelSchema.xsd</em>, to enable IntelliSense and enhance your editing experience in Visual Studio, but unfortunately, it appears to be outdated and doesn’t match the supplied .guidance files. </p>
<p>Instead, you will need to frequently re-run the generator to verify that content you are modifying produces the HTML you expect. You can reduce the amount of time it takes to regenerate output by setting <em>Template Files </em>parameter to regenerate only a the particular type of file you are working on. For example, <em>Business Analyst.htm</em> is generated by the T4 template called <em>Role.htm</em> and you can regenerate only role files like so.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Generate Only Specific Files" border="0" alt="Generate Only Specific Files" src="http://www.olegsych.com/wp-content/uploads/2009/07/image31.png" width="580" height="333" /></p>
<h5>Customizing Guidance Output</h5>
<p>Guidance Generator uses T4 templates located in the <em>HTML_Templates</em> directory to generate output HTML files (in the <em>Supporting Files </em>directory). There is one template file for each major type of XML element in the .guidance file (&lt;Role&gt;/Role.htm, &lt;Activity&gt;/Activity.htm). As you can see, the T4 template files are saved with .htm extension which might be confusing at first. </p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Guidance Generator Templates" border="0" alt="Guidance Generator Templates" src="http://www.olegsych.com/wp-content/uploads/2009/07/image32.png" width="580" height="418" /></p>
<p>The final HTML files rely on additional web resources - JavaScript, Cascading Style Sheet and image files located, respectively, in the <em>Code</em>, <em>CSS </em>and <em>Images </em>sub-folders of the <em>Supporting Files</em> folder where the generated output files are saved. Each guidance (Agile and CMMI) has its own set of supporting files. </p>
<p>To change look and feel of the generated HTML, you can start by changing the <em>CSS\msf.css</em> style-sheet or changing the image files to display your company’s logo. However, if you need more substantial changes, you may have to modify the T4 templates that generate the HTML. For detailed information about T4, please see my previous article, <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit" target="_blank">Text Template Transformation Toolkit</a>.</p>
<h5>Publishing New Guidance</h5>
<p>Once you finish changing the guidance, you can package it in a <a href="http://msdn.microsoft.com/en-us/library/ms243782.aspx" target="_blank">TFS process template</a>, or simply upload it to the <em>Process Guidance </em>folder on your team portal.</p>
<h4>Conclusion</h4>
<p>TFS is a powerful collaboration platform for IT organizations. Although TFS comes with two pre-packaged process templates (MSF Agile and MSF CMMI), it is often beneficial to customize them to better fit the process already used by your organization. It is also important to keep documentation in sync with the process you are using and minimize confusion among the members of the immediate IT team as well as the business users. <em>Guidance Generator</em> is a powerful tool for customizing the built-in process guidance that comes with TFS. Although the Guidance Generator is not very easy to use, the interactive documentation system it produces is well designed, easy to use and would be challenging to replicate in hand-crafted HTML or Word files. In most cases you will want to start with an existing process guidance that most closely matches your current process and customizing it, hopefully by simply removing the MSF concepts you currently don’t use.</p>
<h4>References</h4>
<ul>
<li><a href="http://www.microsoft.com/downloads/details.aspx?familyid=EA75784E-3A3F-48FB-824E-828BF593C34D&amp;displaylang=en" target="_blank">MSF for Agile Software Development</a> (TFS Project Template) </li>
<li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=12A8D806-BB98-4EB4-BF6B-FB5B266171EB&amp;amp;displaylang=en&amp;displaylang=en" target="_blank">MSF CMMI Process Improvement</a> (TFS Project Template) </li>
<li><a href="http://msdn.microsoft.com/en-us/library/bb668982.aspx" target="_blank">How To: Customize a Process Template in Visual Studio Team Foundation Server</a> </li>
<li><a href="http://tfsguide.codeplex.com/" target="_blank">Team Development with Visual Studio Team Foundation Server</a> </li>
<li><a href="http://process.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=5626" target="_blank">VSTS Process Guidance Generator</a> </li>
<li><a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit" target="_blank">Text Template Transformation Toolkit</a> </li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms243782.aspx" target="_blank">Team Foundation Administrators: Customizing Process Templates</a> </li>
</ul>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/DRqLDm-nUrg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/07/customizing-tfs-process-guidance/feed/</wfw:commentRss>
		</item>
		<item>
		<title>T4 Toolbox: Visual Basic as Template Language</title>
		<link>http://www.olegsych.com/2009/07/t4-toolbox-visual-basic-as-template-language/</link>
		<comments>http://www.olegsych.com/2009/07/t4-toolbox-visual-basic-as-template-language/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 20:35:15 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[Code Generation]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[Visual Basic]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/07/t4-toolbox-visual-basic-as-template-language/</guid>
		<description><![CDATA[As of version 9.7, T4 Toolbox now supports Visual Basic as the template language in addition to C#.]]></description>
			<content:encoded><![CDATA[<p>As of version 9.7, <a href="http://t4toolbox.codeplex.com" target="_blank">T4 Toolbox</a> now supports Visual Basic as the template language in addition to C#. You can now create text templates in Visual Basic and perform advanced code generation tasks such as create multiple output files from a single template, automatically add output files to one or more target projects, automatically check out files from source control system if they were modified during regeneration and more.</p>
<p><a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> Toolbox now comes with a set of project item templates for Visual Basic. Here is what you will see when adding a new item to a Visual Basic project.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add New Item dialog" border="0" alt="Add New Item dialog" src="http://www.olegsych.com/wp-content/uploads/2009/07/image22.png" width="580" height="318" /></p>
<p>If you are familiar with these project item templates in C#, you will recognize the code in Visual Basic.</p>
<h6>File</h6>
<pre class="code"><span style="color: black">&lt;#@ </span><span style="color: brown">template </span><span style="color: red">language</span><span style="color: black">=&quot;</span><span style="color: blue">VBv3.5</span><span style="color: black">&quot; </span><span style="color: red">hostspecific</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; </span><span style="color: red">debug</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">output </span><span style="color: red">extension</span><span style="color: black">=&quot;</span><span style="color: blue">txt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">T4Toolbox.tt</span><span style="color: black">&quot; #&gt;
&lt;#
</span><span style="color: green">&#8216; &lt;copyright file=&quot;File1.tt&quot; company=&quot;Your Company&quot;&gt;
&#8216;  Copyright © Your Company. All Rights Reserved.
&#8216; &lt;/copyright&gt;

</span><span style="color: black">#&gt;</span></pre>
<h6>Template</h6>
<pre class="code"><span style="color: black">&lt;#+
</span><span style="color: green">&#8216; &lt;copyright file=&quot;Template1.tt&quot; company=&quot;Your Company&quot;&gt;
&#8216;  Copyright © Your Company. All Rights Reserved.
&#8216; &lt;/copyright&gt;

</span><span style="color: blue">Public Class </span><span style="color: black">Template1
    </span><span style="color: blue">Inherits </span><span style="color: black">Template

    </span><span style="color: blue">Public Overrides Function </span><span style="color: black">TransformText()    

    </span><span style="color: blue">    Return Me.GenerationEnvironment.ToString()
    </span><span style="color: blue">End Function

End Class
</span><span style="color: black">#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>Generator</h6>
<pre class="code"><span style="color: black">&lt;#+
</span><span style="color: green">&#8216; &lt;copyright file=&quot;Generator1.tt&quot; company=&quot;Your Company&quot;&gt;
&#8216;  Copyright © Your Company. All Rights Reserved.
&#8216; &lt;/copyright&gt;

</span><span style="color: blue">Public Class </span><span style="color: black">Generator1
    </span><span style="color: blue">Inherits </span><span style="color: black">Generator

    </span><span style="color: blue">Protected Overrides Sub </span><span style="color: black">RunCore()    

    </span><span style="color: blue">End Sub

End Class
</span><span style="color: black">#&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Entire functionality of the core framework of T4 Toolbox is now available to Visual Basic developers. I have updated the T4 tutorial series to provide examples in both C# and Visual Basic.</p>
<ul>
<li><a href="http://www.olegsych.com/2008/09/t4-tutorial-creatating-your-first-code-generator/">Creating your first code generator</a> </li>
<li><a href="http://www.olegsych.com/2008/09/t4-tutorial-troubleshooting-code-generation-errors/">Troubleshooting code generation errors</a> </li>
<li><a href="http://www.olegsych.com/2008/09/t4-tutorial-debugging-code-generation-files/">Debugging code generation files</a> </li>
<li><a href="http://www.olegsych.com/2008/09/t4-tutorial-creating-reusable-code-generation-templates/">Creating reusable code generation templates</a> </li>
<li><a href="http://www.olegsych.com/2008/09/t4-tutorial-creating-complex-code-generators/">Creating complex code generators</a> </li>
<li><a href="http://www.olegsych.com/2008/10/t4-tutorial-reusing-code-generators-on-multiple-projects/">Reusing code generators on multiple projects</a> </li>
<li><a href="http://www.olegsych.com/2008/11/t4-tutorial-handling-errors-in-code-generators/">Handling errors in code generators</a> </li>
<li><a href="http://www.olegsych.com/2008/11/t4-tutorial-unit-testing-code-generators/">Unit testing code generators</a> </li>
<li><a href="http://www.olegsych.com/2009/02/t4-tutorial-making-code-generators-extensible/">Making code generators extensible</a> </li>
</ul>
<h4>Under the hood</h4>
<p>In order to make Visual Basic support possible, the entire core framework, including <em>TransformationContext</em>, <em>Template, Generator</em> and other classes, was moved from .tt (Text Template) files to .cs (C#) files and is now compiled in the T4Toolbox.dll assembly. Some of the original extensions, such as initialization of the <em>TransformationContext</em> and <em>TestRunner</em> classes had to be reimplemented using custom directive processors.</p>
<p>Note that the set of templates available in Visual Basic is smaller than for C#. That is because ready-to-use code generators, such as <a href="http://www.olegsych.com/2008/12/t4-toolbox-strongly-typed-azman-wrapper-generator/" target="_blank">AzMan wrapper</a>, <a href="http://www.olegsych.com/2008/07/t4-template-for-generating-sql-view-from-csharp-enumeration/" target="_blank">Enum SQL view</a> and <a href="http://www.olegsych.com/2009/05/t4-toolbox-linq-to-sql-schema-generator/" target="_blank">LINQ to SQL model</a> are still implemented in C#. There are no plans to convert them to Visual Basic at this time.</p>
<p>Having the entire core framework code compiled as part of a normal C# class library project, we will finally be able to use <a href="http://sandcastle.codeplex.com/" target="_blank">Sandcastle</a> and generate documentation for T4 Toolbox.</p>
<h4>Known issues</h4>
<p>Developers working primarily with C#, like myself, may be surprised to find that Visual Basic doesn’t display generated output files by default. You have to select the <em>Show All Files</em> button in toolbar of Solution Explorer in Visual Studio in order to see them.</p>
<p>A bigger issue is using Visual Basic in partial templates that contain code meant to be included and never used separately, such as <em>Template </em>and <em>Generator</em> classes. Without the <a href="http://www.olegsych.com/2008/02/t4-template-directive/">template directive</a>, current version of the <a href="http://www.olegsych.com/2009/04/t4-editor-by-tangible-engineering/">T4 Editor</a> assumes the language to be C# and displays a large number of errors for Visual Basic code. As a workaround, you can temporarily add a template directive to such file. To avoid warnings, it has to be removed once the file is <a href="http://www.olegsych.com/2008/02/t4-include-directive/" target="_blank">included</a> and compiled as part of another .tt file because T4 does not support multiple template directives.</p>
<p>This workaround is quite painful to use. To make this work right, the T4 editor needs to somehow infer the language from files without the template directive. One of the possible ways to do this is with file extensions. For example, partial C# text templates could use extension .ttcs and partial Visual Basic templates could use .ttvb. What do you think? Is there a better way to solve this?</p>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/25c1HTS3qMM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/07/t4-toolbox-visual-basic-as-template-language/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MVP Award</title>
		<link>http://www.olegsych.com/2009/07/mvp-award/</link>
		<comments>http://www.olegsych.com/2009/07/mvp-award/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 10:50:54 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/07/mvp-award/</guid>
		<description><![CDATA[I am truly honored to receive the Most Valued Professional (MVP) award from Microsoft. It is both humbling and immensely satisfying to be recognized by this great company. I find it remarkable that a company of this size is so passionate and consistent about supporting its user community and partners. 
Of course the company can [...]]]></description>
			<content:encoded><![CDATA[<p>I am truly honored to receive the <a href="https://mvp.support.microsoft.com/profile/Oleg.Sych">Most Valued Professional (MVP) award from Microsoft</a>. It is both humbling and immensely satisfying to be recognized by this great company. I find it remarkable that a company of this size is so passionate and consistent about supporting its user community and partners. </p>
<p>Of course the company can only be as great as the people working there make it. I would like to thank these great people working at Microsoft for the inspiration and support: <a href="http://www.devfish.net">Joe Healy</a>, <a href="http://blogs.msdn.com/garethj">Gareth Jones</a>, <a href="http://jimblizzard.wordpress.com">Jim Blizzard</a>, <a href="http://blogs.msdn.com/jmprieur">Jean-Mark Prieur</a>, <a href="http://blogs.msdn.com/jbarnes">Jeff Barnes</a>, <a href="http://www.hanselman.com/">Scott Hanselman</a>, <a href="http://blog.wekeroad.com">Rob Caron</a>, <a href="http://blogs.msdn.com/timfis">Tim Fischer</a>. Regardless of whether &quot;community work&quot; is in your job description or not, you helped me in one way or another and I am grateful for that. </p>
<p>This award also would not be possible without the prominent members of the Microsoft community: <a href="http://geekswithblogs.net/sdorman">Scott Doorman</a>, <a href="http://www.vbnetexpert.com">Stan Schultes</a>, <a href="http://davesblog.computerways.com">Dave Noderer</a>, <a href="http://www.swfldev.net">John Dunagan</a>, <a href="http://www.goisc.com">Steve Lane</a>, <a href="http://www.shawnweisfeld.com">Shawn Weisfeld</a>, <a href="http://www.cfdotnet.org/Blog/tabid/65/Default.aspx">Roy Lawson</a>, <a href="http://blogs.windowsclient.net/ken_tucker/default.aspx" target="_blank">Ken Tucker</a> and many many more. So much goes on behind the scenes to keep the user groups going and prepare the code camps. Without your work the development community in Florida wouldn’t be as great as it is today.</p>
<p>And last, but not least, I want to thank my friends and colleagues at <a href="http://www.catapultsystems.com/">Catapult</a>: <a href="http://www.jeffreylodell.com/">Jeff Odell</a>, <a href="http://www.randypatterson.com">Randy Patterson</a>, Terri Burmeister, James McAuliffe. Whether it was buying pizza for a user group meeting, discussing technical issues after hours or having a beer after work, your encouragement and support is very much appreciated. </p>
<p>Sincerely,    <br />Oleg</p>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/E0hwmEgwkWA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/07/mvp-award/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting and compiling T4 Toolbox source code</title>
		<link>http://www.olegsych.com/2009/06/getting-and-compiling-t4-toolbox-source-code/</link>
		<comments>http://www.olegsych.com/2009/06/getting-and-compiling-t4-toolbox-source-code/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 16:57:30 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[T4]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/06/getting-and-compiling-t4-toolbox-source-code/</guid>
		<description><![CDATA[This post provides detailed instructions on how to get source code of T4 Toolbox and compile it on your computer.]]></description>
			<content:encoded><![CDATA[<p><strong><font color="#ff0000">Update</font></strong>: This article is no longer current. Click <a href="http://www.olegsych.com/2009/10/t4-toolbox-support-for-visual-studio-2010/">here</a> for details.</p>
<p>Over the past year, several people have asked me to provide instructions on how to compile <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/"></a><a href="http://www.codeplex.com/t4toolbox">T4 Toolbox</a>.</a> The process is not difficult, but since I don’t do it every day, I have to dig through my email archive to find all the steps every time I need to provide the answer. This seems to be as good time as any to write everything down, so here it goes…</p>
<p>You will need latest versions of the following tools installed in order to compile <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/"></a><a href="http://t4toolbox.codeplex.com" target="_blank">T4 Toolbox</a>.</a> </p>
<ul>
<li><a href="http://www.microsoft.com/visualstudio/en-us/products/professional">Visual Studio 2008 Professional </a>or Team edition </li>
<li><a href="http://code.msdn.microsoft.com/sourceanalysis/">StyleCop</a> </li>
<li><a href="http://wix.sourceforge.net/releases/wix3.feed">WiX 3.0</a> </li>
<li><a href="http://msdn.microsoft.com/en-us/vjsharp/bb188598.aspx">Visual J# 2.0 Redistributable Package</a> </li>
<li><a href="http://sdctasks.codeplex.com">SDC Tasks</a> </li>
</ul>
<h4>Installing Tools</h4>
<p>You can install most of the tools with default options. </p>
<ul>
<li>When installing <em>StyleCop</em>, make sure that <em>MSBuild integration files</em> feature is installed. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="StyleCop installation options" border="0" alt="StyleCop installation options" src="http://www.olegsych.com/wp-content/uploads/2009/06/image.png" width="498" height="384" /></p>
<ul>
<li><em>SDC Tasks</em> don’t have an installer; binary files come in a ZIP archive. For <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> Toolbox, you will need to extract these files to <em>C:\Windows\Microsoft.NET\Framework\v3.5</em> directory. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Extracting SDC Tasks" border="0" alt="Extracting SDC Tasks" src="http://www.olegsych.com/wp-content/uploads/2009/06/image1.png" width="441" height="377" /> </p>
<ul>
<li>Open the extracted <em>Microsoft.Sdc.Common.tasks</em> XML file and comment out the <em>&lt;PropertyGroup/&gt;</em> element in the beginning of the file (enclose it with &lt;!&#8211; and &#8211;&gt;). This element generates warnings during compilation. </li>
<li>Unless you have <em>BizTalk </em>installed on your workstation, you will also need to comment out the entire section at the bottom of this file that declares BizTalk tasks implemented in <em>Microsoft.Sdc.Tasks.BizTalk.dll</em> assembly. Otherwise you will see a large number of errors referring to BizTalk assemblies during compilation. </li>
</ul>
</p>
<h4>Accessing Source Code</h4>
<p>You have two different ways of getting T4 Toolbox source code. If you have not been added to the list of developers, </p>
<ul>
<li>On the <a href="http://t4toolbox.codeplex.com/SourceControl/ListDownloadableCommits.aspx">Source Code tab of the project page,</a> click a <em>Download</em> link for the latest check-in. </li>
</ul>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/06/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Source Code page of T4 Toolbox project on Code Plex" border="0" alt="Source Code page of T4 Toolbox project on Code Plex" src="http://www.olegsych.com/wp-content/uploads/2009/06/image-thumb.png" width="580" height="342" /></a></p>
<ul>
<li>After accepting the license agreement, you will be prompted to download a ZIP archive that contains the latest version of the T4 Toolbox source code. Save the file to your local hard drive first and unblock it before extracting the files. Unless you unblock the ZIP archive first, the Visual Studio will not “trust” it and you will get obscure security errors and warnings later on. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Unblock downloaded ZIP archive" border="0" alt="Unblock downloaded ZIP archive" src="http://www.olegsych.com/wp-content/uploads/2009/06/image3.png" width="368" height="503" /> </p>
<ul>
<li>Extract all files from this archive to a folder on your hard drive, such as <em>C:\T4Toolbox</em>, and open <em>T4Toolbox.sln</em> located in the <em>Source</em> subfolder. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="T4 Toolbox source code on local hard drive" border="0" alt="T4 Toolbox source code on local hard drive" src="http://www.olegsych.com/wp-content/uploads/2009/06/image4.png" width="488" height="316" /> </p>
<ul>
<li>When Visual Studio opens T4 Toolbox solution for the first time, select the <em>Load project normally </em>option. T4Toolbox.csproj uses MSBuild extensions from SDC tasks and StyleCop, you will need to select this option in order to compile it. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.olegsych.com/wp-content/uploads/2009/06/image5.png" width="552" height="390" /> </p>
<p>At this point, you should be able to compile the T4 toolbox. Make changes until it works the way you need it and then <a href="http://t4toolbox.codeplex.com/SourceControl/UploadPatch.aspx">upload the files you modified as a patch on CodePlex</a>. Myself or someone else will take a look at the changes you’ve made and commit them to the main source code of the project.</p>
</p>
</p>
</p>
<h4>Using Team Explorer</h4>
<p>When you are regularly working on T4 Toolbox source code, having to download a source code snapshot becomes a hassle. When your <a href="http://www.codeplex.com/">CodePlex</a> account has been added to the list of <a href="http://t4toolbox.codeplex.com/People/ProjectPeople.aspx">T4 Toolbox developers</a>, you can start using Team Explorer from Visual Studio.</p>
<ul>
<li>Download and install Team Explorer from <a href="http://www.microsoft.com/downloads/details.aspx?familyid=0ED12659-3D41-4420-BBB0-A46E51BFCA86&amp;displaylang=en">here</a>. </li>
<li>Once you have it installed, go to <a href="http://t4toolbox.codeplex.com/">T4 Toolbox page on CodePlex</a>, make sure you are logged (1), open the Source Code tab (2) and then click the Visual Studio Team Explorer link (3). On the right-hand side, you will see the information you will need to use in Team Explorer (4). </li>
</ul>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/06/image6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Team Explorer instructions" border="0" alt="Team Explorer instructions" src="http://www.olegsych.com/wp-content/uploads/2009/06/image-thumb1.png" width="580" height="313" /></a> </p>
<ul>
<li>In <em>Visual Studio</em>, select <em>View-&gt;Team Explorer</em> from the main menu. </li>
<li>In <em>Team Explorer</em>, click <em>Add Existing Team Project</em> button </li>
<li>In the <em>Connect to Team Foundation Server </em>dialog, click <em>Servers</em> button </li>
<li>In the <em>Add/Remove Team Foundation Server </em>dialog, click <em>Add </em>button </li>
<li>In the <em>Add Team Foundation Server</em> dialog, enter server name, port number and protocol from the CodePlex page and click OK. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add T4Toolbox Project to Team Explorer" border="0" alt="Add T4Toolbox Project to Team Explorer" src="http://www.olegsych.com/wp-content/uploads/2009/06/image7.png" width="580" height="480" /> </p>
<ul>
<li>Back in the <em>Add/Remove Team Foundation Server</em> dialog, click <em>Close </em>button </li>
<li>Back in the <em>Connect to Team Foundation Server </em>dialog, select <em>T4Toolbox </em>project and click <em>OK</em> button </li>
<li>Back in <em>Team Explorer</em>, you should now see the <em>T4Toolbox </em>project and its information. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.olegsych.com/wp-content/uploads/2009/06/image8.png" width="292" height="270" /> </p>
<ul>
<li>Double-click the <em>Source Control </em>node to open <em>Source Control Explorer</em> </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Source Control Explorer" border="0" alt="Source Control Explorer" src="http://www.olegsych.com/wp-content/uploads/2009/06/image9.png" width="580" height="294" /> </p>
</p>
</p>
<ul>
<li>In <em>Source Control Explorer</em>, select <em>T4Toolbox </em>folder on the left side and click the <em>Not mapped</em> link on the right. </li>
<li>In the <em>Map </em>dialog, enter name of the local folder you want to use for T4 Toolbox source code and click <em>Map </em>button. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Map workspace dialog" border="0" alt="Map workspace dialog" src="http://www.olegsych.com/wp-content/uploads/2009/06/image10.png" width="580" height="177" /></p>
<ul>
<li>Back in <em>Source Control Explorer</em>, click <em>Get Latest Version</em>&#160; button to download the source code to your local hard drive. </li>
<li>Once downloaded, double-click <em>T4Toolbox.sln </em>in the <em>Source </em>sub-folder to open the solution. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Get Latest Version and Open Solution from Source Control Explorer" border="0" alt="Get Latest Version and Open Solution from Source Control Explorer" src="http://www.olegsych.com/wp-content/uploads/2009/06/image11.png" width="580" height="294" /> </p>
</p>
<p>At this point, you can check files out, change them and check them in. The source control functionality is similar to Visual SourceSafe and Subversion, so it should be familiar to most developers.</p>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/cRyEpqI9yM0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/06/getting-and-compiling-t4-toolbox-source-code/feed/</wfw:commentRss>
		</item>
		<item>
		<title>T4 Toolbox: LINQ to SQL schema generator</title>
		<link>http://www.olegsych.com/2009/05/t4-toolbox-linq-to-sql-schema-generator/</link>
		<comments>http://www.olegsych.com/2009/05/t4-toolbox-linq-to-sql-schema-generator/#comments</comments>
		<pubDate>Tue, 19 May 2009 23:40:53 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Code Generation]]></category>

		<category><![CDATA[LINQ to SQL]]></category>

		<category><![CDATA[SQL]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/05/t4-toolbox-linq-to-sql-schema-generator/</guid>
		<description><![CDATA[This article describes how to use model-first approach to develop database applications using LINQ to SQL and version 9.5 of T4 Toolbox.]]></description>
			<content:encoded><![CDATA[<p>LINQ to SQL <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx">DataContext</a> class provides <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.createdatabase.aspx">CreateDatabase</a> method, which can create an empty database based on the entity model. You can create a new entity model using the built-in <a href="http://msdn.microsoft.com/en-us/library/bb384429.aspx">O/R Designer</a>; generate the application code and create initial version of the database when the application is deployed for the first time. However, once the database is populated with live data, it can no longer be changed by simply re-creating the entire database. Instead, ALTER scripts have to be used to modify the schema and preserve the existing data. In other words, built-in tools allow you to use <em>model-first</em> or <em>model-driven</em> approach with LINQ to SQL only while developing initial version of the database application. The built-in tools don’t support an <em>ongoing</em> model-first development.</p>
<p>This limitation of the built-in LINQ to SQL functionality is one of the reasons developers start using a second tool, such as <a href="http://msdn.microsoft.com/en-us/library/ms171971.aspx">SQL Server Database Diagrams</a>, <a href="http://msdn.microsoft.com/en-us/library/ms182014.aspx">Visio for Enterprise Architects</a> or <a href="http://www.sparxsystems.com">Enterprise Architect by Sparx Systems</a>, and designing the database schema separately from the application model. While this approach works, it significantly increases complexity of the development process. Every change now needs to be made in two places - the database model and the application model. In all but trivial cases, making these changes by hand is too tedious and error-prone to be practical. You are better off choosing one model and somehow synchronizing it with the other. Today, developers typically choose database model as the source of truth and update the entity model based on it, or in other words, use <em>database-driven </em>or <em>database-first </em>approach.</p>
<p>LINQ to SQL includes two tools that allow you to generate .dbml from an existing database - O/R Designer and <a href="http://msdn.microsoft.com/en-us/library/bb386987.aspx">SqlMetal.exe</a> . Unfortunately, both of these tools overwrite existing dbml and don’t allow you to preserve customizations made in the raw relational model imported from the database. SqlMetal also allows you to generate application code from a database directly. By choosing these tools, you are limiting your LINQ to SQL model to a direct representation of your relational database schema and eliminate the possibility of taking advantage of the object-oriented features the framework supports, such as inheritance of entity classes, member access and virtual member modifiers. Alternatively, you can use these tools to create the initial version of the entity model you will customize later, however that brings you back to the issue of maintaining two models separately.</p>
<p>There are third-party tools that make ongoing <em>database-driven </em>development of LINQ to SQL applications more practical. In particular, <a href="http://www.plinqo.com/">PLINQO</a>, a set of code generation templates developed by <a href="http://www.codesmithtools.com">CodeSmith</a>, includes a sophisticated model synchronization logic, which updates .dbml based on database schema while attempting to preserve the customizations. However, these tools don’t eliminate the fundamental requirement of maintaining the two models separately. By itself, this requirement is not a problem. On a large-scale project with a complex database schema, this may well be a necessity. However, on a small- to medium-scale project, having to maintain the two models separately is often an additional, unnecessary burden. </p>
<p><a href="http://www.codeplex.com/t4toolbox/Release/ProjectReleases.aspx">Build 9.5 of T4 Toolbox</a> extends the <a href="http://www.olegsych.com/2009/01/t4-toolbox-linq-to-sql-classes-generator">LINQ to SQL generator</a> introduced in version 9.1 with support for database schema generation. This gives you the ability to generate both application code, such as entity and data context classes, and database code, such as table, primary and foreign key scripts, from a single LINQ to SQL dbml file in your solution. Generated database scripts can be automatically added to a <a href="http://msdn.microsoft.com/en-us/teamsystem/dd408380.aspx">VSTS Database</a> project, which will automatically handle majority of database deployment issues by automatically generating the ALTER scripts. In other words, <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/"></a>combined with VSTS Database edition, <a href="http://www.codeplex.com/t4toolbox">T4 Toolbox</a></a>&#160; allows you to use <em>model-driven</em> or <em>model-first</em> approach for <em>ongoing </em>development of LINQ to SQL applications.</p>
<h4>Usage</h4>
<ul>
<li>Download and install the latest version of T4 Toolbox from <a href="http://www.codeplex.com/t4toolbox/Release/ProjectReleases.aspx">CodePlex</a>. </li>
<li>In Visual Studio, create a new or open an existing C# project and select <em>Project-&gt;Add New Item</em> in the main menu. </li>
<li>In the Add New Item dialog, select <em>Code Generation-&gt;LINQ to SQL model</em> </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add new LINQ to SQL model" border="0" alt="Add new LINQ to SQL model" src="http://www.olegsych.com/wp-content/uploads/2009/05/image6.png" width="580" height="318" /> </p>
<ul>
<li>Enter the name you want to use for the new LINQ to SQL model (.dbml) file. Note that this name also determines name of the <em>DataContext </em>class that will be generated (<em>OrderEntryDataContext</em> will be generated for <em>OrderEntry.dbml</em>). Click the <em>Add </em>button when finished. </li>
</ul>
<p>Just like with the <a href="http://www.olegsych.com/2009/01/t4-toolbox-linq-to-sql-classes-generator">previous version</a> of this template, you will see that two files, a .dbml and a .tt, were added to your project. This time, instead of populating the entity model by dragging and dropping tables from the Server Explorer to the O/R Designer, take a couple of minutes to create the model from scratch and take advantage of some of the LINQ to SQL features like inheritance and associations. There is no need to enter mapping information, such as table or column names and database types. The generator will automatically deduce them from the type names, property names and CLR types respectively. </p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="LINQ to SQL O/R designer" border="0" alt="LINQ to SQL O/R designer" src="http://www.olegsych.com/wp-content/uploads/2009/05/image7.png" width="580" height="317" /></p>
<p>Alternatively, you can download the sample source code accompanying this article. The sample includes an entity model of a simplistic Order Entry application shown above. This model showcases some of the features supported by the code generator, including auto-generated properties (<em>Contact.Id</em>), version properties (<em>Contact.RowVersion</em>), derived types (<em>Employee, Customer, Vendor</em>) , associations (<em>Contact_Employee</em>) and associations where a derived type serves as a parent (<em>Customer_Order</em>). </p>
<ul>
<li>Add a new VSTS database project to the solution. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add new database project" border="0" alt="Add new database project" src="http://www.olegsych.com/wp-content/uploads/2009/05/image8.png" width="580" height="345" /></p>
<p>Make sure to select an appropriate project type in the <em>Database Projects</em>&#160; folder of the <em>Add New Project</em> dialog. Legacy database project template, located under <em>Other Project Types </em>-&gt; <em>Database</em> will not work. If you don’t have Database edition of VSTS installed, you can use any C# project type instead.</p>
<ul>
<li>In the previously created .tt file (<em>OrderEntry.tt</em> in this example), modify the code to assign <em>DatabaseProject </em>property of the <em>LinqToSqlGenerator</em> instance. </li>
</ul>
<pre class="code"><span style="color: black">&lt;#@ </span><span style="color: brown">template </span><span style="color: red">language</span><span style="color: black">=&quot;</span><span style="color: blue">C#v3.5</span><span style="color: black">&quot; </span><span style="color: red">hostspecific</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; </span><span style="color: red">debug</span><span style="color: black">=&quot;</span><span style="color: blue">True</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">output </span><span style="color: red">extension</span><span style="color: black">=&quot;</span><span style="color: blue">log</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">T4Toolbox.tt</span><span style="color: black">&quot; #&gt;
&lt;#@ </span><span style="color: brown">include </span><span style="color: red">file</span><span style="color: black">=&quot;</span><span style="color: blue">T4Toolbox\LinqToSql.tt</span><span style="color: black">&quot; #&gt;
&lt;#
    </span><span style="color: green">// Generate entity classes from a LINQ to SQL class model (.dbml file)
    </span><span style="color: black">LinqToSqlGenerator generator = </span><span style="color: blue">new </span><span style="color: black">LinqToSqlGenerator();
    generator.DbmlFile = </span><span style="color: maroon">&quot;OrderEntry.dbml&quot;</span><span style="color: black">;
    generator.DatabaseProject = </span><span style="color: maroon">@&quot;..\Database\Database.dbproj&quot;</span><span style="color: black">;
</span><span style="color: black">    generator.Run();
#&gt;</span></pre>
<p><img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Generated Database Code" border="0" alt="Generated Database Code" align="right" src="http://www.olegsych.com/wp-content/uploads/2009/05/image9.png" width="238" height="260" /> <em>DatabaseProject</em> value is a path to the database project file, relative to the location of the .tt file. When you save the .tt file, it will generate table, primary and foreign key scripts in this project. At this point, you can build the <a href="http://msdn.microsoft.com/en-us/teamsystem/dd408380.aspx">VSTS Database</a> project and deploy the <em>OrderEntry</em> database to a SQL server. Detailed discussion of the VSTS Database project functionality is outside of scope this article, suffice it to say that this should require only right-clicking the database project in Solution Explorer and selecting <em>Deploy</em> from the context menu.</p>
<p>As you continue using O/R designer to add new properties and types to the LINQ to SQL model, simply right-click the <em>OrderEntry.tt </em>file in the Solution Explorer and select <em>Run Custom Tool</em> to regenerate the database code, build the database project, deploy and let VSTS automatically apply ALTER scripts to the existing database.</p>
<h4>Feature Highlights</h4>
<p>Let’s review some the features supported by this code generator. </p>
<pre class="code"><span style="color: blue">CREATE TABLE </span>dbo.Contact
(
    Id <span style="color: blue">INT NOT NULL IDENTITY</span>,
    Type <span style="color: blue">tinyint</span>,
    <span style="color: blue">RowVersion ROWVERSION</span>,
    FirstName <span style="color: blue">NVARCHAR</span>(4000),
    LastName <span style="color: blue">NVARCHAR</span>(4000),
    StreetAddress <span style="color: blue">NVARCHAR</span>(4000),
    City <span style="color: blue">NVARCHAR</span>(4000),
    State <span style="color: blue">NVARCHAR</span>(4000),
    Zip <span style="color: blue">NVARCHAR</span>(4000),
    Phone <span style="color: blue">NVARCHAR</span>(4000),
    Email <span style="color: blue">NVARCHAR</span>(4000),
    SocialSecurityNumber <span style="color: blue">NVARCHAR</span>(4000),
    EmergencyContactId <span style="color: blue">INT</span>,
    AccountNumber <span style="color: blue">NVARCHAR</span>(4000),
    CreditCardNumber <span style="color: blue">NVARCHAR</span>(4000),
    CreditCardExpiration <span style="color: blue">NVARCHAR</span>(4000)
);</pre>
<h5>Derived types mapped to base table</h5>
<p>The generator automatically generates columns for derived types, such as <em>Employee</em>, in the table of their base type, such as <em>Contact</em>. In particular, <em>SocialSecurityNumber</em> is a property of the Employee type, stored in the <em>Contact </em>table.</p>
<h5>IDENTITY columns</h5>
<p>The generator automatically maps integer properties with <em>Auto Generated Value</em> attribute set to true, such as <em>Id</em>,&#160; to <a href="http://msdn.microsoft.com/en-us/library/ms174979.aspx">IDENTITY</a> columns.</p>
<h5>ROWVERSION data type</h5>
<p>The generator automatically maps byte[] and <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.binary.aspx">Binary</a> properties with <em>Time Stamp</em> attribute set to true, such as <em>RowVersion</em>, to the <a href="http://msdn.microsoft.com/en-us/library/ms182776.aspx">ROWVERSION</a> data type.</p>
<h5>Enum columns</h5>
<p>The generator automatically maps enum properties, such as <em>Type</em> property of the <em>Contact </em>class, to SQL data type INT. You can also specify the server data type explicitly. In the application, the property will be generated with the original enum type.</p>
<pre class="code"><span style="color: blue">private </span><span style="color: #2b91af">ContactType </span>type;

[<span style="color: #2b91af">Column</span>(Name = <span style="color: #a31515">&quot;Type&quot;</span>, <span style="color: green">/* &#8230; */ </span>DbType = <span style="color: #a31515">&quot;tinyint&quot;</span>)]
<span style="color: blue">public </span><span style="color: #2b91af">ContactType </span>Type { <span style="color: green">/* &#8230; */ </span>}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>This allows you to write strongly-typed queries like so:</p>
<pre class="code"><span style="color: blue">var </span>dc = <span style="color: blue">new </span><span style="color: #2b91af">OrderEntryDataContext</span>(<span style="color: #2b91af">Settings</span>.Default.Database);
<span style="color: blue">var </span>employees = <span style="color: blue">from </span>c <span style="color: blue">in </span>dc.Contacts
                <span style="color: blue">where </span>c.Type == <span style="color: #2b91af">ContactType</span>.Employee
                <span style="color: blue">select </span>c;</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<h5>Primary keys</h5>
<pre class="code"><span style="color: blue">ALTER TABLE </span>dbo.Contact
    <span style="color: blue">ADD CONSTRAINT </span>PK_Contact
    <span style="color: blue">PRIMARY KEY CLUSTERED </span>(Id);</pre>
<p>The generator automatically produces a primary key script for properties with <em>Primary Key</em> attribute set to true.</p>
<h5>Delimited Identifiers</h5>
<pre class="code"><span style="color: blue">CREATE TABLE </span>dbo.[Order]
(
    Id <span style="color: blue">INT NOT NULL IDENTITY</span>,
    OrderDate <span style="color: blue">DATETIME NOT NULL</span>,
    EmployeeId <span style="color: blue">INT NOT NULL</span>,
    ProductId <span style="color: blue">INT NOT NULL</span>,
    <span style="color: blue">RowVersion ROWVERSION</span>,
    CustomerId <span style="color: blue">INT NOT NULL</span>,
    Price <span style="color: blue">DECIMAL</span>(29,4) <span style="color: blue">NOT NULL</span>,
    PONumber <span style="color: blue">NVARCHAR</span>(4000)
);</pre>
<p>The generator automatically uses delimited identifiers to avoid errors when original identifier is a reserved SQL keyword, such as <em>Order</em>, or contains spaces, such as <em>Order&#160; Details</em>. Otherwise, the generator uses the original, un-delimited identifiers to improve readability.</p>
<h5>Foreign Keys</h5>
<pre class="code"><span style="color: blue">ALTER TABLE </span>dbo.[Order]
    <span style="color: blue">ADD CONSTRAINT </span>FK_Customer_Order
    <span style="color: blue">FOREIGN KEY </span>(CustomerId)
    <span style="color: blue">REFERENCES </span>dbo.Contact (Id);</pre>
<p>The generator automatically produces foreign key scripts for associations. Note that in case of <em>Customer_Order</em> association, the parent type <em>Customer</em> is actually derived from <em>Contact</em>. The foreign key correctly references the base table, however the generated association property (shown below), is of the derived type, <em>Customer</em>.</p>
<pre class="code">[<span style="color: #2b91af">Association</span>(Name = <span style="color: #a31515">&quot;Customer_Order&quot;</span>, <span style="color: green">/* &#8230; */ </span>IsForeignKey = <span style="color: blue">true</span>)]
<span style="color: blue">public </span><span style="color: #2b91af">Customer </span>Customer { <span style="color: green">/* &#8230; */ </span>}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h4>Sample Source Code</h4>
<p>Sample source code, available for download below, includes a solution with three projects - Model, Database and Application. <em>Model</em> is a C# class library project that contains <em>OrderEntry.dbml</em> (LINQ to SQL model) and <em>OrderEntry.tt</em> (code generator). Entity and Data Context classes are generated in the Model project, while SQL scripts are generated in the <em>Database</em> project. Note that this project requires VSTS Database edition. <em>Application</em> is a C# console application that creates a sample database on the local SQL Server instance, populates it with sample data and executes several queries.</p>
<h4>Closing Thoughts</h4>
<p>The new version of LINQ to SQL generator in T4 Toolbox allows you to use model-first approach for ongoing developing database applications. </p>
<p>So what’s the big deal? <em>Simplicity</em>. </p>
<ul>
<li>There is no need to use a separate modeling tool when developing a database application. You can generate both database and application code without leaving Visual Studio IDE. </li>
<li>There is only one diagram to maintain, which reflects both entity and database models. If you are editing both at the same time, there is no way you can forget update one of them after updating the other.</li>
<li>There is only one step in the code generation process - <em>Run Custom Tool</em> from <em>Solution Explorer</em>. You don’t need to remember to make the changes in the modeling tool, export the schema, build the schema, synchronize the .dbml file with the schema and finally generate the application code from .dbml. </li>
</ul>
<p>What’s the catch then? <em>Limited scalability and flexibility</em>.</p>
<ul>
<li>O/R designer is limited to a single diagram, which puts practical limitations on the number of tables you can manage with this approach. </li>
<li>What you can generate is limited by what you can model in the O/R designer - tables, primary keys and foreign keys. (INSERT, UPDATE and DELETE procedures can also be generated, this is under development now). </li>
<li>Entity and database models are closely related and cannot be developed separately. If you have an existing database, you may not be able to use this approach.</li>
</ul>
<p>Will it work for you? <em>It depends</em>. </p>
<p>This approach will work best on <a href="http://en.wikipedia.org/wiki/Greenfield_project">greenfield projects</a> with a small- to medium-size database and teams who prefer implementing business logic in application code, not stored procedures and triggers. You can certainly optimize time-critical logic by selectively implementing it stored procedures and exposing them in the LINQ to SQL model. However, you will be swimming against the current if you want to rely on the stored procedures extensively. On brownfield projects, this approach will work as well if you have a database of appropriate size and can limit database modifications to the O/R Designer. This approach will not work well if you have a database with hundreds of tables and/or multiple database developers actively creating tables and stored procedures.</p>
<h5>Download</h5>
<ul>
<li><a href="http://www.codeplex.com/t4toolbox/Release/ProjectReleases.aspx">T4 Toolbox</a> </li>
<li><a href="http://www.olegsych.com/wp-content/uploads/2009/05/t4-toolbox-linq-to-sql-schema-generator.zip">Sample source code</a> </li>
</ul>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/5Ppb6-NzUXM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/05/t4-toolbox-linq-to-sql-schema-generator/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Crossing Domain Boundaries: Windows Authentication</title>
		<link>http://www.olegsych.com/2009/05/crossing-domain-boundaries-windows-authentication/</link>
		<comments>http://www.olegsych.com/2009/05/crossing-domain-boundaries-windows-authentication/#comments</comments>
		<pubDate>Sat, 02 May 2009 19:19:00 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[Security]]></category>

		<category><![CDATA[SQL]]></category>

		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/05/crossing-domain-boundaries-windows-authentication/</guid>
		<description><![CDATA[This article describes a set of simple configuration changes and utilities to make most applications using integrated Windows authentication work correctly accross domain boundaries.]]></description>
			<content:encoded><![CDATA[<p>Today, majority of applications on the Microsoft platform rely on or provide support for integrated Windows authentication. Using integrated Windows authentication allows applications to completely avoid persisting custom login credentials and thus eliminates the possibility of an attacker finding them in a configuration file, registry or database and gaining unauthorized access to the system. Microsoft has been promoting use of integrated Windows authentication for years and most software vendors (or perhaps just those who truly care about having customers on the Microsoft platform) support it as an option in their products.</p>
<p>As a consultant, I feel obligated to advise my clients on using integrated Windows authentication as the most secure authentication mechanism for their networks and custom solutions. Unfortunately, as a consultant, I also need to access my clients’ networks from my Catapult laptop, across domain boundaries. This is where integrated Windows authentication makes my job more difficult. Typically, I cannot use my <a href="http://www.catapultsystems.com/">Catapult</a> domain credentials to access resources on the client’s domain and have to supply an alternative set of Windows credentials explicitly. Some applications, like Internet Explorer and Visual Studio are smart enough to prompt you to enter Windows credentials when necessary. While these applications may prompt you to enter credentials more often than you might like, other applications don’t prompt you at all and simply fail. In particular, database applications connecting to SQL Server will not prompt for credentials and display the infamous “<a href="http://search.live.com/results.aspx?q=Cannot+generate+SSPI+context">Cannot establish SSPI context</a>” error when you try use them across domain boundaries.</p>
<p>Thankfully, there is a relatively small number of tricks you need to use to get most applications using integrated Windows authentication work successfully across domain boundaries. These tricks are described below, but before you rush to try them, make sure you have configured <a href="http://www.olegsych.com/2009/04/crossing-domain-boundaries-name-resolution/">name resolution</a> and can successfully connect to a network resource on the target domain using it’s name. Windows authentication will not work without successful name resolution.</p>
<h4>Stored user names and passwords</h4>
<p>Windows allows you to store login credentials for various authentication mechanisms, including Windows or <a href="http://en.wikipedia.org/wiki/Active_Directory">Active Directory</a> credentials. You can store a single Windows login (<em>CLIENT\account</em>) and password for an entire domain (<em>*.client.lan</em>) and Windows will use these credentials automatically whenever you access any computer on it.</p>
<p>Not all types of applications support stored user names and passwords. HTTP applications, such as Internet Explorer, Team Foundation Explorer in Visual Studio, and other applications using WebClient, are one of them. Whenever you type <a href="http://target.client.lan">http://target.client.lan</a> in Internet Explorer, the WebClient will send the matching stored credentials to the target computer automatically, without prompting you. Windows Explorer, Performance Monitor, Event Viewer and other applications relying on network shares also support this mechanism. As long as you have credentials stored, these applications will just work, as if your computer was a member of the target domain. Here is how you set it up.</p>
<ul>
<li>Open <em>User Accounts</em> from <em>Control Panel</em> and click the <em>Manage your network passwords</em> link on the left.</li>
</ul>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image18.png" alt="image18" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="image18" height="279" width="561" /></p>
<ul>
<li>If you are using an older version of Windows, such as XP or 2003 Server, you will need to click the <em>Manage Passwords</em> button on the <em>Advanced</em> tab of the <em>User Accounts</em> dialog.</li>
</ul>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/managepasswordsoldwindows.png" alt="ManagePasswordsOldWindows" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="ManagePasswordsOldWindows" height="455" width="404" /></p>
<ul>
<li>In the <em>Stored User Names and Passwords</em> dialog you need to click the <em>Add </em>button and create a credential entry for the target domain you need to access. Assuming that one of the computers you need to access has a fully-qualified domain name <em>target.client.lan</em>, you want to store credentials for a wildcard <em><strong>*.client.lan</strong></em>, which will used when you access any computers on that domain.</li>
</ul>
<h6><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image29.png" alt="image29" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="image29" height="546" width="461" /> </h6>
<p>You can find more information about storing user names and passwords in the Microsoft knowledge base article <a href="http://support.microsoft.com/kb/281660">281660</a>.</p>
<h4>Internet security zone</h4>
<p>As an added security measure, Internet Explorer will send your current or stored credentials to the target host only when it believes to be a member of the <em>Intranet </em>zone. It will assume that any host addressed with a fully-qualified domain name such as <em>target.client.lan </em>is on the public internet and will not send the credentials automatically. This protects your identity from being stolen by a rouge web site getting your Windows credentials without your permission.</p>
<p>As you can see from the snapshot of Internet Explorer security settings below, even adding the target host to the list of trusted web sites will not work.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image.png" alt="image" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="image" height="483" width="427" /></p>
<p>In order for Windows authentication to work automatically across domain boundaries, without you having to type in your credentials for every page, you will need to add a particular host or its entire domain to the <em>Local Intranet </em>zone.</p>
<ul>
<li>Select <em>Internet Options </em>in <em>Control Panel</em></li>
<li>On the <em>Security </em>tab of the <em>Internet Properties </em>dialog, select <em>Local intranet</em> icon and click <em>Sites </em>button</li>
<li>In the <em>Local intranet </em>dialog, click <em>Advanced </em>button</li>
</ul>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image26.png" alt="image26" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="image26" height="519" width="580" /></p>
<ul>
<li>In the second <em>Local intranet</em> dialog, enter URL of the web site and click <em>Add </em>button.</li>
</ul>
<p>Just like with stored user names and passwords, you can use wildcards that apply to all computers on the target domain. For example, if you enter <em>http://*.client.lan</em>, Internet Explorer will consider <em>target.client.lan </em>and all other computers on the <em>client.lan </em>domain to be in the <em>Local intranet </em>zone and send stored user names and passwords to them automatically.</p>
<h4>WebClient configuration</h4>
<p>Unfortunately, Microsoft Office applications will continue prompting you to enter credentials when accessing files stored on a SharePoint site even after you add the target domain to the Local intranet zone. You will need to modify WebClient configuration in registry to prevent this from happening.</p>
<ul>
<li>Open <em>HKLM\System\CurrentControlSet\Services\WebClient\Parameters</em> key in <em>Registry Editor</em>.</li>
</ul>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image1.png" alt="image" style="display: inline; border-width: 0px" title="image" height="228" width="581" /></p>
<ul>
<li>Double-click the <em>AuthForwardServerList</em> value</li>
<li>In the <em>Edit Multi-String </em>dialog, enter the target URL on a separate line and click OK.</li>
</ul>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image2.png" alt="image" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="image" height="325" width="364" /></p>
<p>This setting also supports wildcards. If you enter <em>http://*.client.lan</em>, Microsoft Office applications will automatically send stored Windows credentials to any SharePoint you access on the <em>client.lan </em>domain. You can learn more about this in Microsoft knowledge base article <a href="http://support.microsoft.com/kb/941050">941050</a>.</p>
<h4>Runas /netonly</h4>
<p>Some applications don’t support stored user names and passwords. For example SQL Server Management Studio will not be able to connect to a database on a different domain using Windows authentication. In these cases you can use the <a href="http://technet.microsoft.com/en-us/library/bb490994.aspx">runas</a> command with <em>netonly</em> option and make the application access network resources under a different set of credentials.</p>
<pre class="code">c:\&gt;runas /user:CLIENT\account /netonly ssms.exe
Enter the password for CLIENT\account:
Attempting to start ssms.exe as user "CLIENT\account" ...</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>When started with the command line above, SQL Server Management Studio will use <em>CLIENT\account</em> to connect to all SQL servers instead of the actual account you used to log into your computer (<em>CATAPULT\osych</em> in my case). In other words, if you need to connect to a database on <em>sqlserver.client.lan</em>, it will use <em>CLIENT\account</em> credentials you supply.</p>
<p>This trick works for all applications that need to connect to SQL Server using integrated windows authentication, not just SQL Server Management Studio. You can use it to run Visual Studio (<em>devenv.exe</em>) and your custom applications.</p>
<p>You can also use the <a href="http://technet.microsoft.com/en-us/sysinternals/cc300361.aspx">ShellRunas</a> utility to provide netonly credentials interactively. Once you downloaded and saved the utility in a permanent location on your hard drive, you will need to register it like so.</p>
<pre class="code">c:\Program Files (x86)\SysInternals&gt;ShellRunas /reg /quiet  

c:\Program Files (x86)\SysInternals&gt;ShellRunas /regnetonly /quiet</pre>
<p>The registration adds <em>Run as different user </em>and <em>Run as different user (netonly)</em> menu items to the shell (i.e. Explorer) context menus for executables.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image3.png" alt="image" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="image" height="561" width="441" /></p>
<p>You can start Visual Studio with netonly context by right-clicking it in the Start menu and selecting the option. Simply provide the credentials required by the target computer you want to access on the other domain and click OK.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image4.png" alt="image" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" title="image" height="353" width="439" /></p>
<p>While you can also run an application completely under another account, not just netonly, this will only work if the domain you are trying to access has a trust relationship with your own domain. Even then, running an application completely under another account is less convenient than netonly because it runs in a different user profile, loosing your settings, shortcuts and favorites. Remember to select netonly option as it is easy to accidentally omit it.</p>
<h4>Local accounts</h4>
<p>If none of the options described above works, your last resort is local accounts and workgroup authentication. In workgroup mode, when there is no Active Directory domain controller, i.e. no centralized authentication authority, Windows relies on having matching local accounts on all computers in a workgroup. For example, an application running under local Administrator on your computer, let’s say it’s called CATLAPTOP, can access computer called TARGET on another domain under <em>its </em>local Administrator account as long as CATLAPTOP\Administrator and TARGET\Administrator accounts have the same passwords on both computers. This works for any account, not just Administrator, subject to permissions assigned to the local account on the target computer.</p>
<p>Using local accounts and workgroup authentication appears to be the recommended approach for some advanced cross-domain networking scenarios, such as <a href="http://msdn.microsoft.com/en-us/library/9y5b4b4f.aspx">remote debugging</a> and SQL Server integrated security. However, these particular scenarios work with runas/netonly approach as well. Unlike the workgroup authentication approach, runas/netonly doesn’t require you to get access to a local account on each target computer. Maintaining these accounts is a hassle for IS administrators and they are typically reluctant to do it. You will probably want to use this option only as a last resort.</p>
<p>If you have to use this option, make sure that your local security policy allows workgroup authentication.</p>
<ul>
<li>Select <em>Local Security Policy</em> from <em>Control Panel</em> under <em>Administrative Tools</em></li>
<li>In the <em>Local Security Policy </em>console, find <em>Security Options </em>under <em>Local Policies</em></li>
</ul>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2009/05/image5.png" alt="image" style="display: inline; border-width: 0px" title="image" height="241" width="580" /></p>
<ul>
<li>Make sure that the <em>Network access: Sharing and security model for local accounts</em> option is set to <em>Classic - local users authenticate as themselves</em>.</li>
</ul>
<h4>Conclusion</h4>
<p>Relying on integrated Windows authentication and Active Directory for centralized authentication is a great way to make information systems in your organization more secure. While making life of users and administrators easier by allowing them to use and manage a single set of login credentials for various network resources and applications, integrated Windows authentication presents an additional barrier when you need to access network resources across domain boundaries. Luckily a relatively small set of configuration changes can help you solve most of these difficulties.</p>
<p>This article describes configuration changes and utilities in the order from easiest and most commonly used to most difficult and infrequently used. You will probably want to store credentials for the new domain and add it to the <em>Local intranet</em> security zone first. This enables most modern applications to access network resources on the target domain without errors and without bothering you with constant prompts for credentials. If you need to access Microsoft Office documents on a SharePoint site, you may also want to configure WebClient to automatically use your stored credentials instead of prompting you every time. For advanced scenarios, such as database applications and remote debugging, use the <em>runas </em>command with <em>netonly </em>option or its interactive equivalent, <em>ShellRunas</em>. If all other options fail, you may have to resort to using local accounts and workgroup authentication.</p>
<p>Name resolution and authentication are not the only problems you have to solve to access network resources. Advanced scenarios may require you to make changes in firewall, group policy, security policy, registry and file configurations a particular application may be affected by. Discussion of these scenarios is outside of scope of this article. You can usually find specific instructions in <a href="http://support.microsoft.com/">Microsoft knowledge base</a>.</p>
<p>&copy;2009 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/olegsych/~4/-0aRuNhgyLs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/05/crossing-domain-boundaries-windows-authentication/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
