<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.3" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Oleg Sych &#187; Oleg Sych</title>
	<link>http://www.olegsych.com</link>
	<description>Me.Write(code)</description>
	<pubDate>Wed, 03 Mar 2010 22:59:17 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.3</generator>
	<language>en</language>
			<item>
		<title>UML Modeling and Code Generation in Visual Studio 2010</title>
		<link>http://www.olegsych.com/2010/01/uml-modeling-and-code-generation-in-visual-studio-2010/</link>
		<comments>http://www.olegsych.com/2010/01/uml-modeling-and-code-generation-in-visual-studio-2010/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 22:47:42 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[Code Generation]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[UML]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2010/01/uml-modeling-and-code-generation-in-visual-studio-2010/</guid>
		<description><![CDATA[This article provides an overview of UML modeling in Visual Studio 2010. Assuming that reader is already familiar with UML, it focuses on custom UML profiles - an extensibility mechanism that can be used to tailor UML models to a particular problem domain. Readers will see an example of such a profile, which extends UML Class Diagrams for database modeling. Finally, the article shows how code can be generated from UML models using T4 text templates.]]></description>
			<content:encoded><![CDATA[<p>This article provides an overview of UML modeling in Visual Studio 2010. Assuming that reader is already familiar with UML, it focuses on custom UML profiles - an extensibility mechanism that can be used to tailor UML models to a particular problem domain. Readers will see an example of such a profile, which extends UML Class Diagrams for database modeling. Finally, the article shows how code can be generated from UML models using T4 text templates.</p>
<p>This article is based on Beta 2 of Visual Studio 2010 Ultimate Edition. To follow the code example you may also want to install <a target="_blank" href="http://www.olegsych.com/2009/04/t4-editor-by-tangible-engineering/">T4 Editor</a> which provides color syntax highlighting and IntelliSense for text templates in Visual Studio.</p>
<h4>UML Modeling in Visual Studio</h4>
<p>Visual Studio 2010 Ultimate Edition includes a fully-featured UML (Unified Modeling Language) support, integrated into the IDE. You can create <a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409432(VS.100).aspx">Use Case</a> diagrams to summarize who uses your application or system, and what they can do with it, <a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409416(VS.100).aspx">Class</a> diagrams to describe logical aspects of data types and their relationships, <a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409389(VS.100).aspx">Sequence</a> diagrams to display interaction between classes, components and actors, <a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409465(VS.100).aspx">Activity</a> diagrams to document flow of an algorithm or a business process and <a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409393(VS.100).aspx">Component</a> diagrams to show structure of a system, and how it can be deployed to a logical environment.</p>
<p>In order to start using UML diagrams in Visual Studio 2010, you first need to create a <em>Modeling Project</em>.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image.png" style="display: inline; border-width: 0px" height="326" width="580" /></p>
<p>Once you have the project created, you can add new diagrams to it.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image1.png" style="display: inline; border-width: 0px" height="326" width="580" /></p>
<p>Here is an example of class diagram you can create.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image2.png" style="display: inline; border-width: 0px" height="522" width="580" /></p>
<p>Model elements can be added to the diagram from Toolbox and configured using Properties window.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image3.png" style="display: inline; border-width: 0px" height="375" width="282" /> <img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image4.png" style="display: inline; border-width: 0px" height="375" width="285" /> </p>
<p>You may have noticed that these diagrams are very similar to the sample diagrams that were included with the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb126235.aspx">DSL (Domain-Specific Language) Toolkit</a> in Visual Studio 2008. While little has changed on the surface, DSL diagrams had a major limitation before Visual Studio 2010. Model information was stored with each diagram, limiting you to a single diagram per model. Needless to say, this limitation made it impossible to use DSL diagrams for all but simplest models.</p>
<p>In Visual Studio 2010, definitions of model elements are stored in a centralized repository as part of your Modeling Project; they can be displayed on multiple diagrams. You can browse contents of the repository using <em>UML Model Explorer</em> and add existing elements to new diagrams by dragging them from this window onto the design surface.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image5.png" style="display: inline; border-width: 0px" height="207" width="282" /> <img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image6.png" style="display: inline; border-width: 0px" height="207" width="282" /></p>
<h5>UML Profiles</h5>
<p>While UML works well for conceptual analysis, the standard models are often too abstract to be useful for logical and physical design. <em>UML Profiles </em>can be used to extend the standard models and adapt them for a particular purpose.</p>
<p>In Visual Studio 2010, a UML Profile is a collection of stereotypes that can be applied to individual model elements. Each stereotype defines a set of attributes that extend definition of the model element it is applied to. For example, Visual Studio includes <em>C# Profile</em> that can be used to extend UML classes with attributes specific to C#.</p>
<p>In order to use stereotypes from a particular profile, first you need to select a package in the <em>UML Model Explorer </em>and apply the profile in the <em>Properties </em>window.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image7.png" style="display: inline; border-width: 0px" height="374" width="283" /> <img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image8.png" style="margin: 0px 5px 0px 0px; display: inline; border-width: 0px" height="374" width="283" /></p>
<p>Once a profile has been specified for the package, you can apply the stereotypes defined by the profile to the elements within the package. Example below shows the <em>C# Class</em> stereotype applied to a UML class, extending it with C#-specific attributes, such as <em>Is Partial</em> and <em>Is Static</em>.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image9.png" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px" height="374" width="472" /></p>
<h5>Custom UML Profiles</h5>
<p>You may want to consider creating a custom UML profile if you rely heavily on modeling in your software development project. Database modeling in particular has been widely adopted by the IT industry, with most of the new projects using database models in some shape or fashion. Unfortunately, no standard UML profile is available for database modeling at the time of this writing. However, the process of creating such a profile in Visual Studio 2010 is relatively straightforward.</p>
<p>Visual Studio 2010 UML profiles are defined in XML files with <em>.profile</em> extension.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image10.png" style="display: inline; border-width: 0px" height="477" width="580" /></p>
<p>The profile definition consists of three sections: <em>metaclasses</em>, <em>propertyTypes</em> and <em>stereotypes</em>.</p>
<p>The <em>metaclasses </em>section lists all UML meta-classes that are extended by stereotypes in the profile. In practical terms, meta-class is a type of model element, such as Package, Class or Association. Meta-classes are identified using fully-qualified type names of the interfaces used in Visual Studio implementation. For example, <a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.uml.classes.iassociation(VS.100).aspx">IAssociation</a> interface represents UML meta-class Association.</p>
<p>The <em>propertyTypes</em> section lists all types used by properties in stereotypes defined by the profile. Standard types, such as <em>System.String</em> can be specified using <em>externalType</em> element. You can also use <em>enumerationType</em> elements to define enumerated types, such as <em>ForeignKeyRule.</em></p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">enumerationType </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">ForeignKeyRule</span>&#8220;<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">enumerationLiterals</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">enumerationLiteral </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">NoAction</span>&#8221; <span style="color: red">displayName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">No Action</span>&#8220;<span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">enumerationLiteral </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Cascade</span>&#8221; <span style="color: red">displayName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Cascade</span>&#8220;<span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">enumerationLiteral </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">SetNull</span>&#8221; <span style="color: red">displayName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Set Null</span>&#8220;<span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">enumerationLiteral </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">SetDefault</span>&#8221; <span style="color: red">displayName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Set Default</span>&#8220;<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">enumerationLiterals</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">enumerationType</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Finally, the <em>stereotypes</em> section contains the actual stereotype definitions. Each stereotype contains a <em>metaclasses</em> element, which specifies the UML meta-class this stereotype extends, and a <em>properties</em> element, which lists the properties that will be added to the target model element when the stereotype is applied to it. </p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">stereotype </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">ForeignKey</span>&#8221; <span style="color: red">displayName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Foreign Key</span>&#8220;<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">metaclasses</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">metaclassMoniker </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">/Sql2008DatabaseProfile/Microsoft.VisualStudio.Uml.Classes.IAssociation</span>&#8221; <span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">metaclasses</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">properties</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">property </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">DeleteRule</span>&#8221; <span style="color: red">displayName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Delete Rule</span>&#8221; <span style="color: red">defaultValue</span><span style="color: blue">=</span>&#8220;<span style="color: blue">NoAction</span>&#8220;<span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">propertyType</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">enumerationTypeMoniker </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">/Sql2008DatabaseProfile/ForeignKeyRule</span>&#8220;<span style="color: blue">/&gt;
      &lt;/</span><span style="color: #a31515">propertyType</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">property</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">property </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">UpdateRule</span>&#8221; <span style="color: red">displayName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Update Rule</span>&#8221; <span style="color: red">defaultValue</span><span style="color: blue">=</span>&#8220;<span style="color: blue">NoAction</span>&#8220;<span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">propertyType</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">enumerationTypeMoniker </span><span style="color: red">name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">/Sql2008DatabaseProfile/ForeignKeyRule</span>&#8220;<span style="color: blue">/&gt;
      &lt;/</span><span style="color: #a31515">propertyType</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">property</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">properties</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">stereotype</span><span style="color: blue">&gt;
</span></pre>
<p>As you can see, the <em>ForeignKey</em> stereotype shown above can be applied to Associations in a UML model. This stereotype defines two properties – <em>DeleteRule</em> and <em>UpdateRule</em>, both of which use the <em>ForeignKeyRule</em> enumerated type defined in the <em>propertyTypes</em> section of our profile.</p>
<p>Notice that various elements in the profile definition have attributes called <em>name </em>and <em>displayName</em>. As you might expect, <em>name</em> specifies internal identifier you can use to access values programmatically, and <em>displayName</em> specifies human-readable text displayed by Visual Studio to the developer.</p>
<h5>Sample Database Profile</h5>
<p>A sample UML profile for database modeling is available for download at the end of this article. It allows you to extend UML class diagrams with stereotypes for modeling database schemas, tables, columns, primary and foreign keys in SQL Server 2008. Here is what a database diagram developed with this profile might look like.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image11.png" style="display: inline; border-width: 0px" height="541" width="580" /></p>
<p>The sample database profile contains the following stereotypes.</p>
<table cellPadding="2" cellSpacing="0" border="1" width="100%">
<tr>
<td vAlign="top" width="115">
<h6>Stereotype</h6>
</td>
<td vAlign="top" width="113">
<h6>Schema</h6>
</td>
<td vAlign="top" width="106">
<h6>Table</h6>
</td>
<td vAlign="top" width="108">
<h6>Column</h6>
</td>
<td vAlign="top" width="110">
<h6>Foreign Key</h6>
</td>
</tr>
<tr>
<td vAlign="top" width="115">
<h6>Applies To</h6>
</td>
<td vAlign="top" width="112">Package</td>
<td vAlign="top" width="105">Class</td>
<td vAlign="top" width="108">Property</td>
<td vAlign="top" width="112">Association</td>
</tr>
<tr>
<td vAlign="top" width="115">
<h6>Properties</h6>
</td>
<td vAlign="top" width="112">Schema Name</td>
<td vAlign="top" width="105"> </td>
<td vAlign="top" width="108">Allow Nulls</p>
<p>Data TypeDefault Value</p>
<p>Is Identity</td>
<td vAlign="top" width="114">Update Rule</p>
<p>Delete Rule</td>
</tr>
</table>
<h5>Profile Installation</h5>
<p>The intended way to install custom UML Profiles is with the help of <a target="_blank" href="http://dotneteers.net/blogs/divedeeper/archive/2009/10/20/devtools-ecosystem-summit-deploying-visual-studio-2010-extensions.aspx">Visual Studio Extensions</a>, new to Visual Studio 2010. The process is well documented on <a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd465143(VS.100).aspx">MSDN</a>, simple and easy to follow. Unfortunately, as of Visual Studio 2010 Beta 2, VSIX deployment of custom profiles appears to be broken. In order to install the sample database profile, I had to resort to manually copying the .profile file to the following directory on a 64-bit Windows 7 installation:</p>
<blockquote><p>C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Team Architecture\UmlProfiles</p></blockquote>
<p>and modifying extension.vsixmanifest file located in this directory to look like this.</p>
<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>&#8220;<span style="color: blue">1.0</span>&#8221; <span style="color: red">encoding</span><span style="color: blue">=</span>&#8220;<span style="color: blue">utf-8</span>&#8220;<span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">Vsix </span><span style="color: red">Version</span><span style="color: blue">=</span>&#8220;<span style="color: blue">1.0.0</span>&#8221; <span style="color: red">xmlns</span><span style="color: blue">=</span>&#8220;<span style="color: blue">http://schemas.microsoft.com/developer/vsx-schema/2010</span>&#8220;<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">Identifier </span><span style="color: red">Id</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Microsoft.VisualStudio.TeamArchitect.ProfileExtension</span>&#8220;<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Name</span><span style="color: blue">&gt;</span>Team Architecture Profile Extension<span style="color: blue">&lt;/</span><span style="color: #a31515">Name</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Author</span><span style="color: blue">&gt;</span>Microsoft<span style="color: blue">&lt;/</span><span style="color: #a31515">Author</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Version</span><span style="color: blue">&gt;</span>10.0<span style="color: blue">&lt;/</span><span style="color: #a31515">Version</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Description</span><span style="color: blue">&gt;</span>Microsoft Visual Studio Team Architecture Profile Extension<span style="color: blue">&lt;/</span><span style="color: #a31515">Description</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Locale</span><span style="color: blue">&gt;</span>1033<span style="color: blue">&lt;/</span><span style="color: #a31515">Locale</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SupportedProducts</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">VisualStudio </span><span style="color: red">Version</span><span style="color: blue">=</span>&#8220;<span style="color: blue">10.0</span>&#8220;<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Edition</span><span style="color: blue">&gt;</span>VSTS<span style="color: blue">&lt;/</span><span style="color: #a31515">Edition</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">VisualStudio</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">SupportedProducts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SupportedFrameworkRuntimeEdition </span><span style="color: red">MinVersion</span><span style="color: blue">=</span>&#8220;<span style="color: blue">4.0</span>&#8221; <span style="color: red">MaxVersion</span><span style="color: blue">=</span>&#8220;<span style="color: blue">4.0</span>&#8221; <span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">SystemComponent</span><span style="color: blue">&gt;</span>true<span style="color: blue">&lt;/</span><span style="color: #a31515">SystemComponent</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">Identifier</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">References </span><span style="color: blue">/&gt;
  &lt;</span><span style="color: #a31515">Content</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">CustomExtension </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Microsoft.VisualStudio.UmlProfile</span>&#8220;<span style="color: blue">&gt;</span>CSharp.Profile<span style="color: blue">&lt;/</span><span style="color: #a31515">CustomExtension</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">CustomExtension </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Microsoft.VisualStudio.UmlProfile</span>&#8220;<span style="color: blue">&gt;</span>StandardProfileL2.Profile<span style="color: blue">&lt;/</span><span style="color: #a31515">CustomExtension</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">CustomExtension </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Microsoft.VisualStudio.UmlProfile</span>&#8220;<span style="color: blue">&gt;</span>StandardProfileL3.Profile<span style="color: blue">&lt;/</span><span style="color: #a31515">CustomExtension</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">CustomExtension </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Microsoft.VisualStudio.UmlProfile</span>&#8220;<span style="color: blue">&gt;</span>Sql2008Database.profile<span style="color: blue">&lt;/</span><span style="color: #a31515">CustomExtension</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">Content</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Vsix</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Notice the <em>CustomExtension</em> added in the end of the file, specifying <em>Sql2008Database.profile</em> as an extension of <em>Microsoft.VisualStudio.UmlProfile</em> type.</p>
<h4>Code Generation</h4>
<p>The simplest way to generate code from a UML model is with the help of <a target="_blank" href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> text templates. Text template is a simple code generator that can be added to any C# and Visual Basic project.</p>
<p><img border="0" src="http://www.olegsych.com/wp-content/uploads/2010/01/image12.png" style="display: inline; border-width: 0px" height="315" width="560" /></p>
<p>Here is the code you need to have in your template to load metadata from a UML model.</p>
<pre style="background-color: white" class="code"><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">template</span><span style="color: #000000"> </span><span style="color: #ff0000">debug</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">true</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="color: #ff0000">hostspecific</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">true</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="color: #ff0000">language</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">C#</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">output</span><span style="color: #000000"> </span><span style="color: #ff0000">extension</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">.sql</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">assembly</span><span style="color: #000000"> </span><span style="color: #ff0000">name</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Interfaces.dll</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">assembly</span><span style="color: #000000"> </span><span style="color: #ff0000">name</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Extensions.dll</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">import</span><span style="color: #000000"> </span><span style="color: #ff0000">namespace</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Classes</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">import</span><span style="color: #000000"> </span><span style="color: #ff0000">namespace</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Extensions</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffe0; color: #000000">
    </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000"> projectPath = </span><span style="background-color: #ffffe0; color: #000000">Host.ResolvePath(</span><span style="background-color: #ffffe0; color: #800000">@&#8221;..\ModelingProject\ModelingProject.modelproj&#8221;</span><span style="background-color: #ffffe0; color: #000000">);
    IModelingProject project = ModelingProject.Load(projectPath);
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="background-color: #ffd700; color: #000000">
</span></pre>
<p>Notice the use of <a target="_blank" href="http://www.olegsych.com/2008/02/t4-assembly-directive/">assembly</a> and <a target="_blank" href="http://www.olegsych.com/2008/02/t4-import-directive/">import</a> directives to reference the Visual Studio assemblies and namespaces that provide API for accessing information in UML models. <a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.itexttemplatingenginehost.resolvepath.aspx">ResolvePath</a> method of the <em>Host</em> object is used to determine absolute path to the modeling project and <a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.uml.extensions.modelingproject.load(VS.100).aspx">Load</a> method of the <em>ModelingProject</em> class is used to open the UML repository.</p>
<p>Here is a complete template that generates SQL scripts for creating tables based on the UML class model extended by our database profile.</p>
<pre style="background-color: white" class="code"><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">template</span><span style="color: #000000"> </span><span style="color: #ff0000">debug</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">true</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="color: #ff0000">hostspecific</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">true</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="color: #ff0000">language</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">C#</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">output</span><span style="color: #000000"> </span><span style="color: #ff0000">extension</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">.sql</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">assembly</span><span style="color: #000000"> </span><span style="color: #ff0000">name</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">System.Core</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">assembly</span><span style="color: #000000"> </span><span style="color: #ff0000">name</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Interfaces.dll</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">assembly</span><span style="color: #000000"> </span><span style="color: #ff0000">name</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Extensions.dll</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">import</span><span style="color: #000000"> </span><span style="color: #ff0000">namespace</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">System.Linq</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">import</span><span style="color: #000000"> </span><span style="color: #ff0000">namespace</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Classes</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">import</span><span style="color: #000000"> </span><span style="color: #ff0000">namespace</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Extensions</span><span style="color: #000000">&#8220;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffff; color: #000000">
    </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000"> projectPath = </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.Host.ResolvePath(</span><span style="background-color: #ffffe0; color: #800000">@&#8221;..\ModelingProject\ModelingProject.modelproj&#8221;</span><span style="background-color: #ffffe0; color: #000000">);
    IModelingProject project = ModelingProject.Load(projectPath);
    </span><span style="background-color: #ffffe0; color: #0000ff">foreach</span><span style="background-color: #ffffe0; color: #000000"> (IType t </span><span style="background-color: #ffffe0; color: #0000ff">in</span><span style="background-color: #ffffe0; color: #000000"> project.Store.Root.OwnedTypes)
    {
        IClass c = t </span><span style="background-color: #ffffe0; color: #0000ff">as</span><span style="background-color: #ffffe0; color: #000000"> IClass;
        </span><span style="background-color: #ffffe0; color: #0000ff">if</span><span style="background-color: #ffffe0; color: #000000"> (c == </span><span style="background-color: #ffffe0; color: #0000ff">null</span><span style="background-color: #ffffe0; color: #000000">) </span><span style="background-color: #ffffe0; color: #0000ff">continue</span><span style="background-color: #ffffe0; color: #000000">;
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="color: #0000ff">create</span><span style="color: #000000"> </span><span style="color: #0000ff">table</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">&lt;#=</span><span style="background-color: #ffffe0; color: #000000"> GetSchema(project.Store.Root) </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">.</span><span style="background-color: #ffd700; color: #000000">&lt;#=</span><span style="background-color: #ffffe0; color: #000000"> c.Name </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
(
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffff; color: #000000">
        </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.PushIndent(</span><span style="background-color: #ffffe0; color: #800000">&#8220;\t&#8221;</span><span style="background-color: #ffffe0; color: #000000">);
        </span><span style="background-color: #ffffe0; color: #0000ff">foreach</span><span style="background-color: #ffffe0; color: #000000"> (IProperty p </span><span style="background-color: #ffffe0; color: #0000ff">in</span><span style="background-color: #ffffe0; color: #000000"> c.OwnedAttributes)
        {
            IStereotypeInstance column = p.AppliedStereotypes.Where(s =&gt; s.Name == </span><span style="background-color: #ffffe0; color: #800000">&#8220;Column&#8221;</span><span style="background-color: #ffffe0; color: #000000">).First();
            </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.WriteLine(p.Name + </span><span style="background-color: #ffffe0; color: #800000">&#8221; &#8220;</span><span style="background-color: #ffffe0; color: #000000"> + GetDataType(column) + GetNull(column) + GetIdentity(column) + </span><span style="background-color: #ffffe0; color: #800000">&#8220;,&#8221;</span><span style="background-color: #ffffe0; color: #000000">);
        }
        </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.PopIndent();
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
);
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffff; color: #000000">
    }
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#+</span><span style="background-color: #ffffff; color: #000000">
    </span><span style="background-color: #ffffe0; color: #0000ff">private</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000"> GetSchema(IPackage package)
    {
        IStereotypeInstance schema = package.AppliedStereotypes.Where(s =&gt; s.Name == </span><span style="background-color: #ffffe0; color: #800000">&#8220;Schema&#8221;</span><span style="background-color: #ffffe0; color: #000000">).First();
        IStereotypePropertyInstance schemaName = schema.PropertyInstances.Where(p =&gt; p.Name == </span><span style="background-color: #ffffe0; color: #800000">&#8220;Name&#8221;</span><span style="background-color: #ffffe0; color: #000000">).First();
        </span><span style="background-color: #ffffe0; color: #0000ff">return</span><span style="background-color: #ffffe0; color: #000000"> schemaName.Value;
    } 

    </span><span style="background-color: #ffffe0; color: #0000ff">private</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000"> GetDataType(IStereotypeInstance column)
    {
        IStereotypePropertyInstance dataType = column.PropertyInstances.Where(p =&gt; p.Name == </span><span style="background-color: #ffffe0; color: #800000">&#8220;DataType&#8221;</span><span style="background-color: #ffffe0; color: #000000">).First();
        </span><span style="background-color: #ffffe0; color: #0000ff">return</span><span style="background-color: #ffffe0; color: #000000"> dataType.Value;
    } 

    </span><span style="background-color: #ffffe0; color: #0000ff">private</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000"> GetNull(IStereotypeInstance column)
    {
        IStereotypePropertyInstance allowNulls = column.PropertyInstances.Where(p =&gt; p.Name == </span><span style="background-color: #ffffe0; color: #800000">&#8220;AllowNulls&#8221;</span><span style="background-color: #ffffe0; color: #000000">).First();
        </span><span style="background-color: #ffffe0; color: #0000ff">return</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">bool</span><span style="background-color: #ffffe0; color: #000000">.Parse(allowNulls.Value) == </span><span style="background-color: #ffffe0; color: #0000ff">true</span><span style="background-color: #ffffe0; color: #000000"> ? </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000">.Empty : </span><span style="background-color: #ffffe0; color: #800000">&#8221; not null&#8221;</span><span style="background-color: #ffffe0; color: #000000">;
    } 

    </span><span style="background-color: #ffffe0; color: #0000ff">private</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000"> GetIdentity(IStereotypeInstance column)
    {
        IStereotypePropertyInstance isIdentity = column.PropertyInstances.Where(p =&gt; p.Name == </span><span style="background-color: #ffffe0; color: #800000">&#8220;IsIdentity&#8221;</span><span style="background-color: #ffffe0; color: #000000">).First();
        </span><span style="background-color: #ffffe0; color: #0000ff">return</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">bool</span><span style="background-color: #ffffe0; color: #000000">.Parse(isIdentity.Value) == </span><span style="background-color: #ffffe0; color: #0000ff">true</span><span style="background-color: #ffffe0; color: #000000"> ? </span><span style="background-color: #ffffe0; color: #800000">&#8221; identity&#8221;</span><span style="background-color: #ffffe0; color: #000000"> : </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000">.Empty;
    }
</span><span style="background-color: #ffd700; color: #000000">#&gt;
</span></pre>
<p>This code uses a foreach loop to iterate through the list of types owned by the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.uml.extensions.imodelstore.root(VS.100).aspx">Root</a> model in our project and generates a create table script for each class. Notice the helper methods, such as <em>GetSchema</em> and <em>GetDataType</em>. They use <a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.uml.classes.ielement.appliedstereotypes(VS.100).aspx">AppliedStereotypes</a> property of the model element to find the stereotype defined in our database profile, such as <em>Schema</em> or <em>Column</em>. Having found the stereotype instance, its properties properties are accessed through the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.uml.classes.istereotypeinstance.propertyinstances(VS.100).aspx">PropertyInstances</a> collection.</p>
<p>Here is the code generated by this text template from our UML model.</p>
<pre class="code"><span style="color: blue">create table </span><span style="color: teal">dbo</span><span style="color: gray">.</span><span style="color: teal">Customer
</span><span style="color: gray">(
    </span><span style="color: teal">FirstName </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">LastName </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">StreetAddress </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">City </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: blue">State nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">PostalCode </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">Id </span><span style="color: blue">int </span><span style="color: gray">not null </span><span style="color: blue">identity</span><span style="color: gray">,
);
</span><span style="color: blue">create table </span><span style="color: teal">dbo</span><span style="color: gray">.</span><span style="color: teal">Product
</span><span style="color: gray">(
    </span><span style="color: teal">Name </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">Price </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">Id </span><span style="color: blue">int </span><span style="color: gray">not null </span><span style="color: blue">identity</span><span style="color: gray">,
);
</span><span style="color: blue">create table </span><span style="color: teal">dbo</span><span style="color: gray">.</span><span style="color: blue">Order
</span><span style="color: gray">(
    </span><span style="color: blue">Date nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">TotalAmount </span><span style="color: blue">nvarchar</span><span style="color: gray">,
    </span><span style="color: teal">Id </span><span style="color: blue">int </span><span style="color: gray">not null </span><span style="color: blue">identity</span><span style="color: gray">,
    </span><span style="color: teal">CustomerId </span><span style="color: blue">int</span><span style="color: gray">,
);
</span><span style="color: blue">create table </span><span style="color: teal">dbo</span><span style="color: gray">.</span><span style="color: teal">OrderItem
</span><span style="color: gray">(
    </span><span style="color: teal">Id </span><span style="color: blue">int </span><span style="color: gray">not null </span><span style="color: blue">identity</span><span style="color: gray">,
    </span><span style="color: teal">OrderId </span><span style="color: blue">int</span><span style="color: gray">,
    </span><span style="color: teal">ProductId </span><span style="color: blue">int</span><span style="color: gray">,
);</span></pre>
<h4>UML vs. DSL</h4>
<p>UML models are high-level abstractions, typically representing systems at conceptual or logical levels. This is an intentional, desired aspect, as it allows you to model a wide variety of of systems without tying the design to any particular platform or implementation. While high-level models serve as an excellent communication tool during envisioning and design phases, during implementation high-level models quickly become outdated, causing confusion. While automated code generation and reverse engineering of models is possible, the process is complex, fragile and requires additional effort.</p>
<p>Comprehensive support for UML is a significant change in direction of Microsoft’s approach to modeling. You may remember that when Domain-Specific Language tools were announced a few years ago, the emphasis was on practical application of modeling throughout the software development lifecycle. It was suggested that models should be considered equal to other source code artifacts, such as .cs/.vb files and .aspx pages. Typical DSL models are lower-level abstractions, representing a system at logical or physical levels. They are predominantly used for code generation and rely on partial classes and inheritance to avoid reverse engineering model information from code back to the model. Examples of DSL models in Visual Studio include LINQ to SQL and Entity Framework designers.</p>
<p>While these approaches to modeling appear to be different, in reality they complement each other, providing us with a full range of modeling capabilities from conceptual and logical, down to physical level. UML models are useful during early stages of a software development project and DSL models work best during implementation and maintenance of the system. It is interesting to note that UML models are actually implemented using DSL tools, so from Visual Studio prospective, UML is simply a DSL for the “unified modeling” domain.</p>
<h4>Conclusion</h4>
<p>As you can see, Visual Studio 2010 Ultimate Edition provides powerful UML modeling tools that can be used for conceptual and logical analysis during software development. UML Profiles can be used to extend standard models and allow modeling information systems at physical level. A limited number of UML profiles is expected to ship with Visual Studio 2010. Custom profiles can be developed to tailor UML models to the needs of individual projects. Combined with T4 Text Templates, this gives developers a powerful tools for model-driven development of information systems, where large portions of the system can be modeled in UML and generated with T4. </p>
<h4>References</h4>
<ul>
<li>MSDN, <a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409436(VS.100).aspx">Developing Models for Software Design</a></li>
<li>Cameron Skinner, <a target="_blank" href="http://blogs.msdn.com/camerons/archive/2010/01/08/uml-profiles-and-visual-studio-2010-ultimate-part-one.aspx">UML Profiles and Visual Studio 2010 Ultimate: Part One</a></li>
<li>Istvan Novak, <a target="_blank" href="http://dotneteers.net/blogs/divedeeper/archive/2009/10/20/devtools-ecosystem-summit-deploying-visual-studio-2010-extensions.aspx">Deploying Visual Studio 2010 Extensions, Part 1</a></li>
<li>Tim Fischer, <a target="_blank" href="http://blogs.msdn.com/timfis/archive/2009/10/31/how-to-generate-code-from-uml-diagrams-in-vs-2010-team-system-beta-2.aspx">How To: Generate Code from Team System UML Diagrams in VS 2010 Beta 2</a> </li>
<li>Oleg Sych, <a target="_blank" href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">Text Template Transformation Toolkit</a></li>
</ul>
<h4>Download</h4>
<p><a target="_blank" href="http://www.olegsych.com/wp-content/uploads/2010/03/sql-2008-uml-profile.zip">Source code</a></p>
<p>&copy;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2010/01/uml-modeling-and-code-generation-in-visual-studio-2010/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Simplifying Entity Framework: Data-Driven Design</title>
		<link>http://www.olegsych.com/2009/12/simplifying-entity-framework-data-driven-design/</link>
		<comments>http://www.olegsych.com/2009/12/simplifying-entity-framework-data-driven-design/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 20:42:00 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[ADO.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Code Generation]]></category>

		<category><![CDATA[Entity Framework]]></category>

		<category><![CDATA[SQL]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[VB]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/12/simplifying-entity-framework-data-driven-design/</guid>
		<description><![CDATA[This article reviews the theory and practice behind ADO.NET Entity Framework, discusses limitations of the current tools it provides and compares the benefits offered by solving the object-relational impedance mismatch against their costs. The article suggest using Entity Framework to improve and reduce costs of data-driven application design, which is prevalent in todays information systems and describes a code generation solution built using T4 Toolbox that can be used to achieve this goal.]]></description>
			<content:encoded><![CDATA[<p>As <a href="http://msdn.microsoft.com/en-us/library/bb399567.aspx">described on MSDN</a>, ADO.NET Entity Framework is a set of technologies that enables developers to work with data in the form of domain-specific objects and properties, such as customers and customer addresses without having to concern themselves with the underlying database tables and columns where this data is stored. Developers can use Entity SQL and traditional ADO.NET reader/adapter/dataset patterns or the new LINQ to Entities to write their code. With LINQ to Entities, the Entity Framework generates strongly-typed entity classes you can use in application code and rely on the runtime to figure out how the data needs to be retrieved from the underlying data source.</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="ADO.NET Entity Framework" border="0" alt="ADO.NET Entity Framework" src="http://www.olegsych.com/wp-content/uploads/2009/12/ado.netentityframework.gif" width="502" height="470" /></p>
<p>Design of Entity Framework has been inspired by the traditional methodology of relational database design which suggests creating a conceptual (class) model, transforming it into logical (relational) model and finally into physical database model. While these activities are typically performed during design and initial implementation of the information system, the Entity Framework implements the physical model, makes the conceptual model a first-class citizen and explicitly defines the mapping model.</p>
<ul>
<li>Conceptual model defines entities and their relationships from the application point of view. This model is defined using Conceptual Schema Definition Language (CSDL) and stored in a separate .csdl file or as part of a combined .edmx file in your project. </li>
<li>Storage model defines entities and their relationships from the database point of view. This model is defined using Store Schema Definition Language (SSDL) and stored in a separate .ssdl file or as part of a combined .edmx file in your project. </li>
<li>Mapping model defines how conceptual model translates into storage model. It is defined using Mapping Specification Language (MSL) and stored in a separate .msl file or as part of a combined .edmx file in your project. </li>
</ul>
<p>The Entity Framework uses these XML-based models to transform create, read, update, and delete operations against entities and relationships in the conceptual model to equivalent operations in the data source. The storage and mapping models can change as needed without requiring changes to the conceptual model, data classes, or application code. Because storage models are provider-specific, you can work with a consistent conceptual model across various data sources. The Entity Data Model even supports mapping entities in the conceptual model to stored procedures in the data source.</p>
<h4>What is wrong with this picture?</h4>
<p>Entity Framework was designed to overcome the <a href="http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch">object-relational impedance mismatch</a> and allow you to hide a difficult-to-use legacy database schema behind a modern, object-oriented entity model and make developers more productive. This description almost sounds to good to be true. Unfortunately, just like other frameworks designed to solve complex problems, the Entity Framework tends to make simple things difficult.</p>
<p>Having three separate database layers (or models) in the Entity Data Model means having each entity represented three times, each from a different point of view. Every time you need to make a change in your database model, which also needs to be implemented in the application, you have to make it three times. Take adding a new column to a table as an example. No matter in which order you do it, you still have to add a new property to the conceptual model, a new column to the storage model and a new mapping from one to the other. This task is tedious and error prone even with the best modeling tools imaginable. Unfortunately, Entity Framework designer limits you to a single diagram, which gradually becomes more difficult to use as the number of entities increases, becoming virtually useless when it exceeds 50.</p>
<p>In simplistic terms, this all means that Entity Data Model is three times as complex as a traditional database model. To implement all but trivial logic, either one developer has to understand all three models or you have to have two or more people involved in implementing it. In the end, you have to spend three times more effort to develop and maintain the EDM, you are three times more likely to make mistakes, i.e. the cost of having the EDM in your solutions is three times higher than the cost of a solution that uses a single hypothetical data model.</p>
<h4>What is the alternative?</h4>
<p>Majority of information systems in existence today are built using relational databases and data-oriented code. A tremendous amount of tooling, knowledge and experience has been developed over the past two decades by the industry, making low-cost development resources readily available. Although solving the object-relational impedance mismatch sounds very good in theory, in practice, the overall cost of such a solution is typically higher, in part due to additional effort required to maintain three separate database models and in part due to additional knowledge and experience required from developers.</p>
<p>However, the existing as well as new information systems could benefit tremendously from having a modern, strongly-typed, LINQ-enabled, automatically generated data access layer (DAL). Such a DAL would allow to significantly reduce the amount of plumbing code developers have to write today with <a href="http://msdn.microsoft.com/en-us/library/system.data.common.dbconnection.aspx">DbConnection</a>, <a href="http://msdn.microsoft.com/en-us/library/system.data.common.dbdatareader.aspx">DbDataReader</a> and <a href="http://msdn.microsoft.com/en-us/library/system.data.dataset.aspx">DataSet</a> classes without requiring significant changes to the application architecture. In other words, as long as the effort required to maintain such a DAL is less than the effort required to maintain the data access code manually, we can take advantage of the language and data access enhancements offered by the current version of the .NET framework while reducing the overall cost of the information systems.</p>
<h4>Entity Framework DAL generator in T4 Toolbox</h4>
<p>In order to implement an automatically generated DAL based on Entity Framework today, you would have to use <a href="http://msdn.microsoft.com/en-us/library/bb387165.aspx" target="_blank">EdmGen</a>. Unfortunately, it does not give you access to some of the options supported by the framework. The new version of <a href="http://t4toolbox.codeplex.com/">T4 Toolbox</a> includes a code generator that encapsulates the functionality built into Entity Framework and makes it available in <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/" target="_blank">T4</a>-based code generation scripts. This code generator is based on the idea of using database modeling tools built into Visual Studio, which are easier to use and unlike Entity Framework’s own designer, are proven to work on the number of tables typically found in real-world databases. In the rest of this article we will review the process of using this code generator to illustrate its pros and cons.</p>
<h5>Getting Started</h5>
<p>In order to follow this sample, you need to have Visual Studio 2008 or 2010, Standard Edition or higher, SQL Server Express 2005 or later, <a href="http://t4toolbox.codeplex.com/">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>
<ul>
<li>Create a new C# or Visual Basic console application project. </li>
<li>Add a new item to your project and select the <em>Code Generation</em>-&gt;<em>Entity Framework Database</em> template in the <em>Add New Item </em>dialog. </li>
</ul>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Entity Framework Database template in the Add New Item Dialog" border="0" alt="Entity Framework Database template in the Add New Item Dialog" src="http://www.olegsych.com/wp-content/uploads/2009/12/image3.png" width="580" height="326" /></p>
<ul>
<li>Enter the desired database name and click <em>Add</em>. </li>
</ul>
<p>This template adds a new, empty SQL Express database to your project. Unfortunately, Visual Studio automatically displays the the Data Source Configuration Wizard whenever you add a .mdf file to a project. Normally, you would use it to create a data access layer with built-in visual designers. In this case, we have the entire data access layer generated automatically for us.</p>
<ul>
<li>Click <em>Cancel </em>in the <em>Data Source Configuration Wizard.</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="Data Source Configuration Wizard" border="0" alt="Data Source Configuration Wizard" src="http://www.olegsych.com/wp-content/uploads/2009/12/image4.png" width="580" height="486" /> <img style="border-right-width: 0px; margin: 5px 0px 5px 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Database and generated files in Solution Explorer" border="0" alt="Database and generated files in Solution Explorer" align="right" src="http://www.olegsych.com/wp-content/uploads/2009/12/image5.png" width="240" height="362" /></p>
<p>Notice that a number of files have been added to your project, including a .mdf file (SQL database), a .ldf file (SQL log), a .tt file (code generator), a .cs/.vb file (entity classes and object context), a .Views.cs/.vb file (precompiled entity views), a .csdl file (conceptual model), a .ssdl file (storage model) and a .msl file (mapping model). If you are using Visual Basic, you will need to click &quot;<em>Show All Files</em>” button in solution explorer in order to see the files nested under .mdf and .tt.</p>
<h5>Database Modeling</h5>
<p>Visual Studio includes a subset of database modeling functionality from SQL Server Management Studio, including database diagrams, table designers, key and relationship designers.</p>
<ul><img style="border-right-width: 0px; margin: 0px 40px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Database in Server Explorer." border="0" alt="Database in Server Explorer." align="left" src="http://www.olegsych.com/wp-content/uploads/2009/12/image6.png" width="239" height="260" />
<li>Double-click the .mdf file in <em>Solution Explorer </em>(shown above)<em>.</em> This will cause the database to be opened in <em>Server Explorer</em> (shown on the left). </li>
<li>Right-click <em>Database Diagrams</em> in <em>Server Explorer</em> and select <em>Add New Diagram</em> from the context menu. </li>
<li>The first time you add a diagram to a database, Visual Studio will prompts you to create database objects required for diagramming. Click Yes when prompted. </li>
</ul>
<p>Use the diagram to create a new database model.</p>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/12/image7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Database Diagram Toolbar" border="0" alt="Database Diagram Toolbar" src="http://www.olegsych.com/wp-content/uploads/2009/12/image-thumb3.png" width="580" height="22" /></a><a href="http://www.olegsych.com/wp-content/uploads/2009/12/image8.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Database Diagram Designer" border="0" alt="Database Diagram Designer" src="http://www.olegsych.com/wp-content/uploads/2009/12/image-thumb4.png" width="580" height="498" /></a></p>
<p><img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Use Properties Window to configure tables and columns." border="0" alt="Use Properties Window to configure tables and columns." align="left" src="http://www.olegsych.com/wp-content/uploads/2009/12/image9.png" width="240" height="301" />Database diagrams allow you to quickly model tables and their relationships. You can use the <em>Properties Window</em> of Visual Studio to configure individual tables and columns selected on the design surface. The toolbar and context menu provide access to commands that allow you to model keys, relationships, indexes, unique and check constraints, as well as customize the look of your diagram for display and print, add text annotations and more. Also, unlike with Entity Framework designer, you can create additional diagrams when the number of tables is too big to fit on a single diagram. This seemingly trivial feature is crucial for large database models.</p>
<p>Having the model database included in your project has several important benefits. It is placed under source control with the rest of the files in your project, giving you the ability to go back to previous versions when necessary. Although it may seem excessive to check in an entire database in source control, the size of a .mdf file is comparable to the size of a similar database model stored in a Visio .vsd file or an Enterprise Architect .eap file. You can also use the database file itself to store any seed data you need and with “Copy to Output Directory” option turned on, the database deployment becomes a simple xcopy on <a href="http://en.wikipedia.org/wiki/Greenfield_project" target="_blank">greenfield projects</a>.</p>
<ul>
<li>Make sure to save changes you make in any database diagram or designers you open before you proceed to the next step of generating code. </li>
</ul>
<h5>Code Generation</h5>
<ul>
<li>Double-click the .tt file in <em>Solution Explorer </em>(shown above) to open it in the <a href="http://www.olegsych.com/2009/04/t4-editor-by-tangible-engineering/">T4 Editor</a>. </li>
</ul>
<h6>C#</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">template</span><span style="color: #000000"> </span><span style="color: #ff0000">language</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">C#</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="color: #ff0000">hostspecific</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">True</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">output</span><span style="color: #000000"> </span><span style="color: #ff0000">extension</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">cs</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox\EntityFramework.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffe0; color: #000000">
    <span style="background-color: #ffffe0; color: #0000ff">var</span> generator = </span><span style="background-color: #ffffe0; color: #0000ff">new</span><span style="background-color: #ffffe0; color: #000000"> EntityFrameworkGenerator();
    generator.DatabaseFile = </span><span style="background-color: #ffffe0; color: #800000">&quot;Database1.mdf&quot;</span><span style="background-color: #ffffe0; color: #000000">;
    generator.Run();
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span></pre>
<h6>VB</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">template</span><span style="color: #000000"> </span><span style="color: #ff0000">language</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">VB</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="color: #ff0000">hostspecific</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">True</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">output</span><span style="color: #000000"> </span><span style="color: #ff0000">extension</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">vb</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox\EntityFramework.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffe0; color: #000000">
    </span><span style="background-color: #ffffe0; color: #0000ff">Dim</span><span style="background-color: #ffffe0; color: #000000"> generator </span><span style="background-color: #ffffe0; color: #0000ff">As</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">New</span><span style="background-color: #ffffe0; color: #000000"> EntityFrameworkGenerator()
    generator.DatabaseFile = </span><span style="background-color: #ffffe0; color: #800000">&quot;Database1.mdf&quot;</span><span style="background-color: #ffffe0; color: #000000">
    generator.LanguageOption = LanguageOption.GenerateVBCode
    generator.Run()
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span></pre>
<p>This is a <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> code generation script that creates a new instance of <em>EntityFrameworkGenerator</em>, configures its properties and uses it to generate all model and code files required for a ready-to-use data access layer based on Entity Framework. Note that this script is not directly associated with the database file in the Visual Studio project and has to be run manually.</p>
<ul>
<li>Right-click the .tt file in <em>Solution Explorer</em> and select <em>Run Custom Tool</em> from its context menu to trigger the code generation. </li>
<li>Double-click the&#160; generated .cs/.vb file in <em>Solution Explorer</em> to open it in the Visual Studio editor. If you are using Visual Basic, you will need to click “<em>Show All Files</em>” in the toolbar of <em>Solution Explorer</em> in order to see this file. </li>
</ul>
<h6>C#</h6>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/12/image10.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Generated C# Code" border="0" alt="Generated C# Code" src="http://www.olegsych.com/wp-content/uploads/2009/12/image-thumb5.png" width="580" height="456" /></a></p>
<h6>VB</h6>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/12/image11.png"><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/12/image-thumb6.png" width="580" height="477" /></a></p>
<p>This generated file contains definitions of both entity classes and object context required to access the database using LINQ to Entities.</p>
<p>Also note the other generated code file, in our example Database1.Views.cs/.vb. This file contains <a href="http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx" target="_blank">pre-generated views</a>, which significantly improve reduce the amount of time required to connect to a database using an Entity Framework object context for the first time. This can take tens of seconds even on a medium-size database with a hundred of tables. While this performance hit does not have a meaningful effect on applications in production due to Entity Framework caching the views on per-AppDomain basis, this delay is a significant problem for developers who need to recompile and restart the application frequently. The Entity Framework designer does not generate views automatically, causing much frustration for developers and, perhaps, being the main reason for Entity Frameworks reputation of having poor performance.</p>
<h5>Coding</h5>
<p>At this point, you have everything you need to start coding against your new database using LINQ to Entities.</p>
<ul>
<li>Double-click Program.cs or Module.vb in <em>Solution Explorer</em>. </li>
<li>Enter the following code in the editor. </li>
</ul>
<h6>C#</h6>
<pre class="code">
<span style="color: blue">using </span>System;
<span style="color: blue">using </span>System.Linq; 

<span style="color: blue">namespace </span>EfDalSampleCS
{
  <span style="color: blue">class </span><span style="color: #2b91af">Program
  </span>{
    <span style="color: blue">static void </span>Main(<span style="color: blue">string</span>[] args)
    {
      <span style="color: blue">var </span>context = <span style="color: blue">new </span><span style="color: #2b91af">Database1Entities</span>();
      context.AddToProducts(<span style="color: blue">new </span><span style="color: #2b91af">Product</span>() { ProductName = <span style="color: #a31515">&quot;Internet Explorer&quot;</span>, UnitPrice = <span style="color: brown">0 </span>});
      context.AddToProducts(<span style="color: blue">new </span><span style="color: #2b91af">Product</span>() { ProductName = <span style="color: #a31515">&quot;Windows 7 Ultimate&quot;</span>, UnitPrice = <span style="color: brown">319.99M </span>});
      context.SaveChanges(); 

      <span style="color: blue">var </span>products = <span style="color: blue">from </span>p <span style="color: blue">in </span>context.Products <span style="color: blue">select </span>p;
      <span style="color: blue">foreach </span>(<span style="color: blue">var </span>product <span style="color: blue">in </span>products)
      {
          <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&quot;{0} ({1})&quot;</span>, product.ProductName, product.UnitPrice);
      }
    }
  }
}&#160; </pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>VB</h6>
<pre class="code">
<span style="color: blue">Imports </span>System
<span style="color: blue">Imports </span>System.Linq
<span style="color: blue">Imports </span>EfDalSampleVB.EfDalSampleVB 

<span style="color: blue">Module </span><span style="color: #2b91af">Module1
    </span><span style="color: blue">Sub </span>Main()
        <span style="color: blue">Dim </span>context <span style="color: blue">As New </span><span style="color: #2b91af">Database1Entities
        </span>context.AddToProducts(<span style="color: blue">New </span><span style="color: #2b91af">Product</span>() <span style="color: blue">With </span>{.ProductName = <span style="color: #a31515">&quot;Internet Explorer&quot;</span>, .UnitPrice = <span style="color: brown">0</span>})
        context.AddToProducts(<span style="color: blue">New </span><span style="color: #2b91af">Product</span>() <span style="color: blue">With </span>{.ProductName = <span style="color: #a31515">&quot;Windows 7 Ultimate&quot;</span>, .UnitPrice = <span style="color: brown">319.99</span>})
        context.SaveChanges() 

        <span style="color: blue">Dim </span>products = <span style="color: blue">From </span>p <span style="color: blue">In </span>context.Products <span style="color: blue">Select </span>p
        <span style="color: blue">For Each </span>product <span style="color: blue">In </span>products
            <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&quot;{0} ({1})&quot;</span>, product.ProductName, product.UnitPrice)
        <span style="color: blue">Next
    End Sub
End Module</span> 

<span style="color: blue"></span>&#160;</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<ul>
<li>Press F5 to run the program. You may want to set a breakpoint and observe execution of the program in Visual Studio debugger. </li>
</ul>
<p>A couple of things are worth explaining. How does this code know which database to connect to? The answer lies in the default constructor of <em>Database1Entities</em> class, which is generated to use a connection string with the same name. This connection string was automatically added to the configuration file when we added <em>Database1.mdf</em> to our project.</p>
<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">connectionStrings</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">add </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">Database1Entities</span>&quot;
      <span style="color: red">connectionString</span><span style="color: blue">=
      </span>&quot;
        <span style="color: blue">metadata=res://*/Database1.csdl
                |res://*/Database1.ssdl
                |res://*/Database1.msl;
        provider=System.Data.SqlClient;
        provider connection string=
        &#8216;
          Data Source=.\SQLEXPRESS;
          AttachDbFilename=|DataDirectory|\Database1.mdf;
          Integrated Security=True;
          User Instance=True
        &#8216;
      </span>&quot;
      <span style="color: red">providerName</span><span style="color: blue">=</span>&quot;<span style="color: blue">System.Data.EntityClient</span>&quot; <span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">connectionStrings</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/12/image12.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="image" border="0" alt="image" align="right" src="http://www.olegsych.com/wp-content/uploads/2009/12/image-thumb7.png" width="226" height="240" /></a>Metadata section of the connection string specifies that .csdl, .ssdl and .msl files are embedded as resources in the executable. Provider section of the connection string instructs Entity Framework to use ADO.NET SQL Client to connect to the database. The provider connection string section contains the traditional connection string and indicates that SQL Server Express edition will be used to automatically attach the database file located in <em>DataDirectory</em>. For windows applications (such as the console app we have here), <em>DataDirectory</em> token refers to the directory where the&#160; executable is located. Our database file is copied to the output directory because the “Copy to Output Directory” option was set to “Copy Always” for the .mdf file in our project.</p>
<h5>Customizing the list of database objects exposed by DAL</h5>
<p>You may have noticed that among the generated entity classes, we also have <em>sysdiagrams</em>, which was actually the table created by SQL Server when we added the first diagram to our database. Unless you are planning to access this table from your application, it would be best to remove it from the data access layer. You can can do that by adding a <em>filter</em> to the code generator.</p>
<ul>
<li>Add the following code to the .tt file before <em>generator.Run()</em> method is called. </li>
</ul>
<h6>C#</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffffe0; color: #000000">  generator.Filters.Add(
    </span><span style="background-color: #ffffe0; color: #0000ff">new</span><span style="background-color: #ffffe0; color: #000000"> EntityStoreSchemaFilterEntry(
      </span><span style="background-color: #ffffe0; color: #0000ff">null</span><span style="background-color: #ffffe0; color: #000000">,   </span><span style="background-color: #ffffe0; color: #008000">// catalog</span><span style="background-color: #ffffe0; color: #000000">
      </span><span style="background-color: #ffffe0; color: #0000ff">null</span><span style="background-color: #ffffe0; color: #000000">,   </span><span style="background-color: #ffffe0; color: #008000">// schema</span><span style="background-color: #ffffe0; color: #000000">
      </span><span style="background-color: #ffffe0; color: #800000">&quot;sys%&quot;</span><span style="background-color: #ffffe0; color: #000000">, </span><span style="background-color: #ffffe0; color: #008000">// name</span><span style="background-color: #ffffe0; color: #000000">
      EntityStoreSchemaFilterObjectTypes.Table,
      EntityStoreSchemaFilterEffect.Exclude));</span></pre>
<h6>VB</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffffe0; color: #000000">  generator.Filters.Add( _
    </span><span style="background-color: #ffffe0; color: #0000ff">New</span><span style="background-color: #ffffe0; color: #000000"> EntityStoreSchemaFilterEntry( _
      </span><span style="background-color: #ffffe0; color: #0000ff">Nothing</span><span style="background-color: #ffffe0; color: #000000">, _
      </span><span style="background-color: #ffffe0; color: #0000ff">Nothing</span><span style="background-color: #ffffe0; color: #000000">, _
      </span><span style="background-color: #ffffe0; color: #800000">&quot;sys%&quot;</span><span style="background-color: #ffffe0; color: #000000">,  _
      EntityStoreSchemaFilterObjectTypes.Table, _
      EntityStoreSchemaFilterEffect.Exclude))</span></pre>
<p>This code creates a filter entry object that indicates that all tables whose name starts with <em>“sys”</em> should be excluded from the generated DAL. <em>EntityFrameworkGenerator</em> class contains a property called <em>Filters</em> to which you can add one or more filter entries and make sure that only appropriate database objects are accessible through the DAL. For complete details, please refer to <a href="http://msdn.microsoft.com/en-us/library/system.data.entity.design.entitystoreschemafilterentry.aspx" target="_blank">EntityStoreSchemaFilterEntry</a>, <a href="http://msdn.microsoft.com/en-us/library/system.data.entity.design.entitystoreschemafilterobjecttypes.aspx" target="_blank">EntityStoreSchemaFilterObjectTypes</a> and <a href="http://msdn.microsoft.com/en-us/library/system.data.entity.design.entitystoreschemafiltereffect.aspx" target="_blank">EntityStoreSchemaFilterEffect</a> on MSDN.</p>
<p>Unfortunately, not all of the possible combinations of object types and filter effects are supported by the underlying Entity Framework generator. For example, creating a filter entry to include functions in the DAL has no effect because the functions are only automatically generated in the storage model (.ssdl) and not in the conceptual model (.csdl). In other words, you cannot access stored procedures using the DAL produced by this code generator in its current version.</p>
<h5>Customizing pluralization of entity class names and set names</h5>
<p>Entity Framework 4.0 in Visual Studio 2010 provides an option to automatically convert table names to singular form in names of entity classes and to plural form in names of entity set properties. Without this automatic conversion, both entity name and set name would be either in plural form or singular form, depending on the naming convention you use in your database model. This poses a significant limitation in Entity Framework 3.5 in Visual Studio 2008, making the resulting DAL more confusing. A <a href="http://blogs.msdn.com/efdesign/archive/2008/12/02/pluralization.aspx" target="_blank">complete discussion of pluralization</a> by the Entity Framework team is available on their blog.</p>
<p>The code generator in T4 Toolbox has the pluralization turned on by default in Visual Studio 2010. If you need to generate the DAL without pluralization, perhaps for compatibility reasons, you can turn this option off by adding the following line to the .tt file before <em>generator.Run()</em> method is called.</p>
<h6>C#</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffffe0; color: #000000">  generator.Pluralize = </span><span style="background-color: #ffffe0; color: #0000ff">false</span><span style="background-color: #ffffe0; color: #000000">;</span></pre>
<h6>VB</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffffe0; color: #000000">  generator.Pluralize = </span><span style="background-color: #ffffe0; color: #0000ff">False</span></pre>
<p>This option is not available in Visual Studio 2008 because the underlying code generator in Entity Framework does not support it.</p>
<h5>Customizing generation of foreign key properties</h5>
<p>Entity Framework 4.0 in Visual Studio 2010 also provides an option to generate and use foreign key properties (such as Order.ProductId) in addition to navigation properties (such as Order.Product). Detailed discussion of <a href="http://blogs.msdn.com/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx" target="_blank">foreign key properties</a> is also available on the Entity Framework team blog.</p>
<p>The code generator in T4 Toolbox offers an option to generate foreign key properties, however you need to turn it on explicitly, by adding the following line to the .tt file before <em>generator.Run()</em> method is called.</p>
<h6>C#</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffffe0; color: #000000">  generator.GenerateForeignKeyProperties = </span><span style="background-color: #ffffe0; color: #0000ff">true</span><span style="background-color: #ffffe0; color: #000000">;</span></pre>
<h6>VB</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffffe0; color: #000000">  generator.GenerateForeignKeyProperties = </span><span style="background-color: #ffffe0; color: #0000ff">True</span><span style="background-color: #ffffff; color: #000000"></span></pre>
<p>This option is not available in Visual Studio 2008 because the underlying code generator in Entity Framework does not support it.</p>
<h5>Customizing location of the model database</h5>
<p>When storing the model database under source control is not desirable on your project, you can change the code generator to use a standalone database as the model.</p>
<ul>
<li>Change the .tt file to specify a connection string instead of the database file. </li>
</ul>
<h6>C#</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">template</span><span style="color: #000000"> </span><span style="color: #ff0000">language</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">C#</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="color: #ff0000">hostspecific</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">True</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">output</span><span style="color: #000000"> </span><span style="color: #ff0000">extension</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">cs</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox\EntityFramework.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffe0; color: #000000">
  EntityFrameworkGenerator generator = </span><span style="background-color: #ffffe0; color: #0000ff">new</span><span style="background-color: #ffffe0; color: #000000"> EntityFrameworkGenerator();
  generator.ConnectionString = </span><span style="background-color: #ffffe0; color: #800000">&quot;Server=.;Database=Northwind;Integrated Security=True&quot;</span><span style="background-color: #ffffe0; color: #000000">;
  generator.Run();
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span></pre>
<h6>VB</h6>
<pre style="background-color: white" class="code"><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">template</span><span style="color: #000000"> </span><span style="color: #ff0000">language</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">VB</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="color: #ff0000">hostspecific</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">True</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">output</span><span style="color: #000000"> </span><span style="color: #ff0000">extension</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">vb</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">include</span><span style="color: #000000"> </span><span style="color: #ff0000">file</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">T4Toolbox\EntityFramework.tt</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffe0; color: #000000">
  </span><span style="background-color: #ffffe0; color: #0000ff">Dim</span><span style="background-color: #ffffe0; color: #000000"> generator </span><span style="background-color: #ffffe0; color: #0000ff">As</span><span style="background-color: #ffffe0; color: #000000"> </span><span style="background-color: #ffffe0; color: #0000ff">New</span><span style="background-color: #ffffe0; color: #000000"> EntityFrameworkGenerator()
  generator.ConnectionString = </span><span style="background-color: #ffffe0; color: #800000">&quot;Server=.;Database=Northwind;Integrated Security=True&quot;</span><span style="background-color: #ffffe0; color: #000000">
  generator.LanguageOption = LanguageOption.GenerateVBCode
</span><span style="background-color: #ffffe0; color: #000000">  generator.Run()
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span></pre>
<p>When you save the modified .tt file, the DAL will be regenerated based on the metadata in the database you specified in the connection string. By default, database name determines the name of the generated object context class. Changing the name of the database from <em>Database1</em> to <em>Northwind</em> will change the name of the context class from <em>Database1Entities </em>to <em>NorthwindEntities</em>.</p>
<ul>
<li>Rename the .tt file to match the name of the database (<em>Northwind.tt</em> in our example)<em>.</em> </li>
</ul>
<p>Although this is not required, renaming the code generation script will make the names of the generated .csdl, .ssdl and .msl files match the name of the database and make the solution easier to understand.</p>
<ul>
<li>Update the configuration file to match the changes made in generated code. </li>
</ul>
<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">connectionStrings</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">add </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">NorthwindEntities</span>&quot;
      <span style="color: red">connectionString</span><span style="color: blue">=
      </span>&quot;
        <span style="color: blue">metadata=res://*/Northwind.csdl
                |res://*/Northwind.ssdl
                |res://*/Northwind.msl;
        provider=System.Data.SqlClient;
        provider connection string=
        &#8216;
          Server=.;
          Database=Northwind;
          Integrated Security=True;
        &#8216;
      </span>&quot;
      <span style="color: red">providerName</span><span style="color: blue">=</span>&quot;<span style="color: blue">System.Data.EntityClient</span>&quot; <span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">connectionStrings</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span></pre>
<p>In particular, the name of the connection string has to match the new name of the object context class (<em>NorthwindEntities</em> in this example); file names in the metadata section of the connection string have to match the names of the generated model files (<em>Northwind.csdl</em>, <em>Northwind.ssdl </em>and <em>Northwind.msl</em> in this example); and finally, the provider connection string section of the connection string has to point to the actual database in your current environment.</p>
<p>Note that database connection string is present in both .tt and .config files. In this example, the same Northwind database on local SQL server is used during both code generation and execution. You may want to use different databases for these purposes, perhaps an empty local database for code generation and a shared database for development and testing. In that case, make sure to use appropriate connection strings in the .tt and .config files.</p>
<h5>Other customization options</h5>
<p>Additional details about customization options are available in the T4 Toolbox documentation installed as part of the Visual Studio 2008 help collection. If you have it installed, you can click <a href="ms-help://MS.VSCC.v90/MS.VSIPCC.v90/T4Toolbox/T4Toolbox/html/AllMembers_T_T4Toolbox_EntityFramework_EntityFrameworkGenerator.htm" target="_blank">here</a> to open the list of properties available for you to use in the code generation script.</p>
<h4>Conclusion</h4>
<p>ADO.NET Entity Framework allows you to access database in object-oriented manner at the cost of additional effort required to maintain conceptual, storage and mapping model. While sounding good in theory, solving the object-relational impedance mismatch in practice typically increases the cost of information systems due to additional knowledge, experience and effort it requires with tools available today. By implementing an automatically-generated, modern, strongly-typed, LINQ-enabled data access layer based on Entity Framework, we can improve developer productivity and reduce the system development cost without introducing the overhead and complexity of fully featured object-relational mapping. Unlike the tools built into Entity Framework, the database modeling functionality in Visual Studio and the code generator described in this article allow you to use Entity Framework effectively with more than just a few dozen tables. Unfortunately, due to limitations in the current version of Entity Framework, the solution described in this article does not allow accessing stored procedures and functions through the automatically generated DAL, making it inferior compared to a similar DAL based on LINQ to SQL today.</p>
<h5><strong>Download</strong></h5>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/12/efdalsample.zip">Sample source code</a></p>
<p>&copy;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/12/simplifying-entity-framework-data-driven-design/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Presentation: Code Generation with T4</title>
		<link>http://www.olegsych.com/2009/12/presentation-code-generation-with-t4/</link>
		<comments>http://www.olegsych.com/2009/12/presentation-code-generation-with-t4/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 10:59:42 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/12/presentation-code-generation-with-t4/</guid>
		<description><![CDATA[Back in October, I presented a session on Code Generation with T4 at the Developer Tools Ecosystem Summit. This session provides an overview of developing code generators with T4, starting with template syntax and transformation process, to template debugging, to integration and deployment. During this session you see a sample code generator built from scratch, [...]]]></description>
			<content:encoded><![CDATA[<p>Back in October, I presented a session on Code Generation with <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a> at the <a href="http://msdn.microsoft.com/en-us/vsx/cc512752.aspx">Developer Tools Ecosystem Summit</a>. This session provides an overview of developing code generators with T4, starting with template syntax and transformation process, to template debugging, to integration and deployment. During this session you see a sample code generator built from scratch, using Logical Class Diagrams as a source of metadata. Logical Class Diagrams are one of the powerful new UML modeling tools shipping in Visual Studio 2010 Ultimate Edition. The session covers the breadth of the functionality offered by T4 today and highlights the improvements made in Visual Studio 2010. </p>
<p>You can watch the recording on <a href="http://channel9.msdn.com/posts/VSIPMarketing/VSX206-Code-Generation-with-T4/">Channel 9</a>. In case you need to fast forward, here is the original outline I created for this session. </p>
<ul>
<li>Template Syntax and Transformation Process (5 minutes) </li>
<li>Demo – Create simple template (15 minutes) </li>
<li>Processing Directives (10 minutes) </li>
<li>Demo – Template debugging (5 minutes) </li>
<li>Template Deployment (5 minutes) </li>
<li>Custom Tool Integration (5 minutes) </li>
<li>Pre-compiled templates (5 minutes) </li>
<li>What’s new in 2010 (5 minutes) </li>
</ul>
<p>Unfortunately, the code example for this session was originally developed using Visual Studio 2010 Beta 1. In Beta 2, the APIs for accessing UML metadata are different and much easier to use. Here is a working template, inspired by <a href="http://blogs.msdn.com/timfis/archive/2009/10/31/how-to-generate-code-from-uml-diagrams-in-vs-2010-team-system-beta-2.aspx">Tim Fischer’s example</a>:</p>
<p> <a href="http://11011.net/software/vspaste"></a>
<pre class="code"><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">template</span><span style="color: #000000"> </span><span style="color: #ff0000">debug</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">true</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="color: #ff0000">hostspecific</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">true</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="color: #ff0000">language</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">C#</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">output</span><span style="color: #000000"> </span><span style="color: #ff0000">extension</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">.cs</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">assembly</span><span style="color: #000000"> </span><span style="color: #ff0000">name</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Interfaces.dll</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">assembly</span><span style="color: #000000"> </span><span style="color: #ff0000">name</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Extensions.dll</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">import</span><span style="color: #000000"> </span><span style="color: #ff0000">namespace</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Classes</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="background-color: #ffd700; color: #000000">&lt;#@</span><span style="color: #000000"> </span><span style="color: #a52a2a">import</span><span style="color: #000000"> </span><span style="color: #ff0000">namespace</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #0000ff">Microsoft.VisualStudio.Uml.Extensions</span><span style="color: #000000">&quot;</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
</span><span style="color: #0000ff">using</span><span style="color: #000000"> System;

</span><span style="color: #0000ff">namespace</span><span style="color: #000000"> ClassLibrary
{
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffff; color: #000000">
    </span><span style="background-color: #ffffe0; color: #0000ff">string</span><span style="background-color: #ffffe0; color: #000000"> projectPath = </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.Host.ResolvePath(</span><span style="background-color: #ffffe0; color: #800000">@&quot;..\ModelingProject\ModelingProject.modelproj&quot;</span><span style="background-color: #ffffe0; color: #000000">);
    </span><span style="background-color: #ffffe0; color: #0000ff">using</span><span style="background-color: #ffffe0; color: #000000"> (IModelingProject project = ModelingProject.Load(projectPath))
    {
        </span><span style="background-color: #ffffe0; color: #0000ff">foreach</span><span style="background-color: #ffffe0; color: #000000"> (IType t </span><span style="background-color: #ffffe0; color: #0000ff">in</span><span style="background-color: #ffffe0; color: #000000"> project.Store.Root.OwnedTypes)
        {
            IClass c = t </span><span style="background-color: #ffffe0; color: #0000ff">as</span><span style="background-color: #ffffe0; color: #000000"> IClass;
            </span><span style="background-color: #ffffe0; color: #0000ff">if</span><span style="background-color: #ffffe0; color: #000000"> (c == </span><span style="background-color: #ffffe0; color: #0000ff">null</span><span style="background-color: #ffffe0; color: #000000">) </span><span style="background-color: #ffffe0; color: #0000ff">continue</span><span style="background-color: #ffffe0; color: #000000">;
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
    </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> </span><span style="background-color: #ffd700; color: #000000">&lt;#=</span><span style="background-color: #ffffe0; color: #000000"> c.Name </span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
    {
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffff; color: #000000">
        </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.PushIndent(</span><span style="background-color: #ffffe0; color: #800000">&quot;\t\t&quot;</span><span style="background-color: #ffffe0; color: #000000">);
        </span><span style="background-color: #ffffe0; color: #0000ff">foreach</span><span style="background-color: #ffffe0; color: #000000"> (IProperty p </span><span style="background-color: #ffffe0; color: #0000ff">in</span><span style="background-color: #ffffe0; color: #000000"> c.OwnedAttributes)
        {
            </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.WriteLine(</span><span style="background-color: #ffffe0; color: #800000">&quot;public &quot;</span><span style="background-color: #ffffe0; color: #000000"> + p.Type.Name + </span><span style="background-color: #ffffe0; color: #800000">&quot; &quot;</span><span style="background-color: #ffffe0; color: #000000"> + p.Name + </span><span style="background-color: #ffffe0; color: #800000">&quot;;&quot;</span><span style="background-color: #ffffe0; color: #000000">);
        }
        </span><span style="background-color: #ffffe0; color: #0000ff">this</span><span style="background-color: #ffffe0; color: #000000">.PopIndent();
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
    }
</span><span style="background-color: #ffd700; color: #000000">&lt;#</span><span style="background-color: #ffffff; color: #000000">
        }
    }
</span><span style="background-color: #ffd700; color: #000000">#&gt;</span><span style="color: #000000">
}</span></pre>
<p>&copy;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/12/presentation-code-generation-with-t4/feed/</wfw:commentRss>
		</item>
		<item>
		<title>T4 Toolbox: Automatic Template Transformation</title>
		<link>http://www.olegsych.com/2009/11/t4-toolbox-automatic-template-transformation/</link>
		<comments>http://www.olegsych.com/2009/11/t4-toolbox-automatic-template-transformation/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 18:29:11 +0000</pubDate>
		<dc:creator>Oleg Sych</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Code Generation]]></category>

		<category><![CDATA[Custom Tool]]></category>

		<category><![CDATA[T4]]></category>

		<category><![CDATA[Visual Basic]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.olegsych.com/2009/11/t4-toolbox-automatic-template-transformation/</guid>
		<description><![CDATA[This article discusses new features of T4 Toolbox that allow you trigger code generation automatically when the input or model file changes and while still giving developers the ability to customize the code generation using rich template-based functionality of T4.]]></description>
			<content:encoded><![CDATA[</p>
<p>By default in <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4</a>, the code generation (a.k.a. template transformation) occurs when you save a template (.tt) file or select <em>Run Custom Tool</em> from its context menu in <em>Solution Explorer</em>. This works very well while you are actively developing the code generator, making changes in the template file and saving it to see the generated code. However, once development of the code generator itself is finished and your entire development team begins using it, this way of triggering code generation becomes less than ideal. </p>
<p>If your template generates code from metadata stored in a separate file, such as <a href="http://www.olegsych.com/2009/01/t4-toolbox-linq-to-sql-classes-generator/">the LINQ to SQL .dbml file</a>, it is easy for a developer to change the input file and forget to regenerate the code using the code generator in a separate T4 file. This mistake can lead to unnecessary frustration and wasted effort, especially when a T4-based code generator replaces a built-in code generator, such as <em>MSLinqToSqlGenerator</em>, which generates code automatically whenever the input file is saved.</p>
<p>You can eliminate the waste of effort and frustration by triggering your T4-based code generator automatically, whenever the input file is saved. This can be accomplished using a proven Visual Studio extensibility mechanism – Custom Tools. In this article, we will review how you can create your own custom tool or simply use the one provided by the <a href="http://t4toolbox.codeplex.com/" target="_blank">T4 Toolbox</a>. </p>
<h4>Custom Tools</h4>
<p>A custom tool - sometimes referred to as a <em>single file generator </em>- can be used to extend the Visual Basic, Visual C#, and Visual J# project systems in Visual Studio. A custom tool is a COM component that implements the <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivssinglefilegenerator.aspx" target="_blank">IVsSingleFileGenerator</a> interface. Using this interface, a custom tool transforms a single input file into a single output file. The result of the transformation may be source code, or any other output that is required. T4 itself provides a custom tool called <em>TextTemplatingFileGenerator</em>, which is automatically associated with .tt files and performs template transformation. Before you can use a custom tool, you must <a href="http://msdn.microsoft.com/en-us/library/bb166527.aspx" target="_blank">register it with the system or in the Visual Studio local registry</a>. You can find complete details about custom tools and single file generators <a href="http://msdn.microsoft.com/en-us/library/bb166817.aspx" target="_blank">in Visual Studio SDK</a>.</p>
<h4>T4-Based Custom Tool</h4>
<p>One way to automate T4-based code generation, is to create a custom tool that will be associated with your input file. When the input file is modified, Visual Studio will invoke this custom tool; the tool will load a T4 template either from an embedded resource or an external file and use <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.vshost.itexttemplating.aspx" target="_blank">ITextTemplating</a> service to generate the code. </p>
<p>There are different ways to implement such custom tool. If you are building a modeling solution using <a href="http://msdn.microsoft.com/en-us/library/bb126235.aspx" target="_blank">Domain-Specific Language</a> tools, <a href="http://blogs.msdn.com/jmprieur" target="_blank">Jean-Mark Prieur</a> provides an excellent example in Part 4 of the <a href="http://code.msdn.microsoft.com/DSLToolsLab" target="_blank">DSL Tools Lab</a>. Alternatively, you can follow <a href="http://msdn.microsoft.com/en-us/library/bb166817.aspx" target="_blank">instructions in Visual Studio SDK</a>, which requires more work, but does not have a dependency on DSL toolkit. Either way, you will want to take advantage of the built-in functionality provided by T4 and inherit your custom tool from the <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.vshost.templatedcodegenerator.aspx" target="_blank">TemplatedCodeGenerator</a> as Jean-Mark suggests.</p>
<p>Although implementing a T4-based custom tool is not difficult, the custom tool requires registration, which means having an installation program. If you are a tool developer, this is not a problem – you probably already have one. If you are an application developer, this is just another bit of extra work that doesn’t directly contribute to your product, the extra work you want to avoid.</p>
<h4>T4ScriptFileGenerator</h4>
<p>T4 Toolbox (version <a href="http://t4toolbox.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=30030" target="_blank">9.10</a> or later) provides a ready-to-use custom tool called <em>T4ScriptFileGenerator</em>. You can associate it with a particular file using <em>Solution Explorer </em>and <em>Properties </em>window as shown below. </p>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/11/image2.png"><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/11/image-thumb2.png" width="278" height="257" /></a> <a href="http://www.olegsych.com/wp-content/uploads/2009/11/image3.png"><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/11/image-thumb3.png" width="280" height="257" /></a></p>
<p>First time you save the input file (<em>Northwind.dbml </em>in our example) after assigning <em>T4ScriptFileGenerator</em> as its <em>Custom Tool,</em> it will create an empty .tt file similar to this.</p>
<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">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;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Note that the new .tt file has the usual <em>TextTemplatingFileGenerator</em> custom tool associated with it.</p>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/11/image4.png"><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/11/image-thumb4.png" width="278" height="257" /></a> <a href="http://www.olegsych.com/wp-content/uploads/2009/11/image5.png"><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/11/image-thumb5.png" width="280" height="257" /></a> </p>
<p>When you add the actual code generation logic and save this file, T4 engine will transform it automatically, as you would expect. In this example, we will modify <em>Northwind.tt</em> file to look like this.</p>
<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; #&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">    </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;Northwind.dbml&quot;</span><span style="color: black">;
    generator.Run();
#&gt;</span></pre>
<p>Now if we go back and modify our input file, <em>Northwind.dbml</em>, the <em>T4ScriptFileGenerator </em>will reuse the existing T4 script, <em>Northwind.tt</em>, and trigger the code generation. In other words, the Northwind.tt file is being transformed automatically whenever we change the input file, Northwind.dbml.</p>
<p>This configuration process is easy to follow and once you are done, simply check your project into your source control and the custom tool configuration will be preserved in the project file itself. To begin using this code generator, other developers on your team simply need to have T4 Toolbox installed on their computers and get latest version of the project source code. </p>
<p>However, if you are building T4-based code generators that can be created and configured by others, perhaps your development team or external customers, you may want to save them the trouble of performing these steps manually every time they need to create a new code generator.</p>
<h4>T4ScriptFileGeneratorWizard</h4>
<p>T4 Toolbox (version <a href="http://t4toolbox.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34574" target="_blank">9.12</a> or later) also allows you to automatically associate <em>T4ScriptFileGenerator</em> with an input file using a <a href="http://www.olegsych.com/2008/03/code-generation-with-visual-studio-templates/" target="_blank">Visual Studio Project Item Template</a>. Simply put both the input file and the code generation script (.tt) file in the template as described in the article mentioned above and provide a VSTEMPLATE file similar to this.</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">VSTemplate </span><span style="color: red">Version</span><span style="color: blue">=</span>&quot;<span style="color: blue">2.0.0</span>&quot; <span style="color: red">xmlns</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.microsoft.com/developer/vstemplate/2005</span>&quot; <span style="color: red">Type</span><span style="color: blue">=</span>&quot;<span style="color: blue">Item</span>&quot;<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">TemplateData</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">DefaultName</span><span style="color: blue">&gt;</span>DataClasses.dbml<span style="color: blue">&lt;/</span><span style="color: #a31515">DefaultName</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Name</span><span style="color: blue">&gt;</span>LINQ to SQL Model<span style="color: blue">&lt;/</span><span style="color: #a31515">Name</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Description</span><span style="color: blue">&gt;</span>LINQ to SQL entity classes and schema objects.<span style="color: blue">&lt;/</span><span style="color: #a31515">Description</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">ProjectType</span><span style="color: blue">&gt;</span>CSharp<span style="color: blue">&lt;/</span><span style="color: #a31515">ProjectType</span><span style="color: blue">&gt;
</span><span style="color: blue">  &lt;/</span><span style="color: #a31515">TemplateData</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">TemplateContent</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">References</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">Reference</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;</span>System<span style="color: blue">&lt;/</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Reference</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">Reference</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;</span>System.Core<span style="color: blue">&lt;/</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Reference</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">Reference</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;</span>System.Data.Linq<span style="color: blue">&lt;/</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Reference</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">References</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">ProjectItem </span><span style="color: red">SubType</span><span style="color: blue">=</span>&quot;<span style="color: blue">Designer</span>&quot; <span style="color: red">TargetFileName</span><span style="color: blue">=</span>&quot;<span style="color: blue">$fileinputname$.dbml</span>&quot; <span style="color: red">ReplaceParameters</span><span style="color: blue">=</span>&quot;<span style="color: blue">true</span>&quot;<span style="color: blue">&gt;</span>Dbml.xml<span style="color: blue">&lt;/</span><span style="color: #a31515">ProjectItem</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">ProjectItem </span><span style="color: red">SubType</span><span style="color: blue">=</span>&quot;&quot; <span style="color: red">TargetFileName</span><span style="color: blue">=</span>&quot;<span style="color: blue">$fileinputname$.tt</span>&quot; <span style="color: red">ReplaceParameters</span><span style="color: blue">=</span>&quot;<span style="color: blue">true</span>&quot;<span style="color: blue">&gt;</span>LinqToSqlModel.tt<span style="color: blue">&lt;/</span><span style="color: #a31515">ProjectItem</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">TemplateContent</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">WizardExtension</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;</span>T4Toolbox, Version=9.11.21.1, Culture=neutral, PublicKeyToken=7e313accbcce84dc<span style="color: blue">&lt;/</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">FullClassName</span><span style="color: blue">&gt;</span>T4Toolbox.VisualStudio.T4ScriptFileGeneratorWizard<span style="color: blue">&lt;/</span><span style="color: #a31515">FullClassName</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">WizardExtension</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">VSTemplate</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Notice the use of <em>&lt;WizardExtension/&gt;</em> to associate the <em>T4ScriptFileGenerationWizard </em>with this project item template. This wizard extension will assign <em>T4ScriptFileGenerator</em> as a custom tool to the <em>root item </em>unfolded by the template - $fileinputname$<em>.dbml or Northwind.dbml</em> file in this example. If the project item template contains a T4 script file with the matching name (<em>$fileinputname$.tt</em>), the wizard extension will also make sure the code in it is preserved and used for code generation. If the project item template does not contain a T4 script file, an empty .tt file will be created instead. </p>
<p>Remember that T4 Toolbox has a separate assemblies for Visual Studio 2008 (<em>T4Toolbox.dll</em>) and Visual Studio 2010 (<em>T4Toolbox.10.0.dll</em>). The VSTEMPLATE example above is for Visual Studio 2008. In 2010, you have to change the &lt;WizardExtension&gt; to look like this.</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">WizardExtension</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;</span>T4Toolbox.10.0, Version=9.11.21.1, Culture=neutral, PublicKeyToken=7e313accbcce84dc<span style="color: blue">&lt;/</span><span style="color: #a31515">Assembly</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">FullClassName</span><span style="color: blue">&gt;</span>T4Toolbox.VisualStudio.T4ScriptFileGeneratorWizard<span style="color: blue">&lt;/</span><span style="color: #a31515">FullClassName</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">WizardExtension</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>As you have already guessed, T4 Toolbox uses <em>T4ScriptFileGenerator </em>and <em>T4ScriptFileGeneratorWizard</em> in its <em>LINQ to SQL model</em> sample code generator for C#. You can see it in action yourself.</p>
<p><a href="http://www.olegsych.com/wp-content/uploads/2009/11/image6.png"><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/11/image-thumb6.png" width="580" height="326" /></a> </p>
<h4>Conclusion</h4>
</p>
<p>Although the built-in mechanism for triggering template transformation in T4 works well during development of a code generator, it often leads to mistakes during its normal use, when developers primarily modify the code generation model or input file. There are different ways of triggering the code generation automatically when the input file changes. In this article we discussed one of these approaches, based on Custom Tools. While it is possible to completely hide code generation from developers with this approach, doing so would prevent developers from being able to take advantage of rich template-based customization capabilities offered by T4. The <em>T4ScriptFileGenerator</em> in T4 Toolbox allows you get the best of both options: have the code generation occur automatically when the input file changes and still allow developers to customize the code generator by changing the T4 template.</p>
<p>&copy;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/11/t4-toolbox-automatic-template-transformation/feed/</wfw:commentRss>
		</item>
		<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;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></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;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></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;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></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;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></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;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></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;2010 <a href="http://www.olegsych.com">Oleg Sych</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.olegsych.com/2009/07/t4-toolbox-visual-basic-as-template-language/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
