<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4244396226795190974</atom:id><lastBuildDate>Sat, 07 Jul 2012 10:48:55 +0000</lastBuildDate><title>Visual T4 Blog</title><description>T4 template editing and code generation based on Microsoft's built-in T4 technology</description><link>http://blog.visualt4.com/</link><managingEditor>noreply@blogger.com (Visual T4)</managingEditor><generator>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/VisualT4Blog" /><feedburner:info uri="visualt4blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-5671578807791276469</guid><pubDate>Mon, 08 Nov 2010 06:42:00 +0000</pubDate><atom:updated>2010-11-07T22:42:44.906-08:00</atom:updated><title>Visual T4 beta 1 for VS 2010 is now available!</title><description>&lt;p&gt;During the last month we have been receiving a constant flow of daily emails like “&lt;em&gt;where the heck is the VS2010 version???”&lt;/em&gt; so we are pleased to announce the public availability of the beta 1 bits which you can download from the Extension Manager dialog or by hand from the &lt;a href="http://goo.gl/TNtC7" target="_blank"&gt;Visual Studio Gallery&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Visual T4 for VS 2010 is an almost complete re-write from the VS 2008 version. We wanted to take advantage of the new WPF-based editor and MEF introduced in VS 2010 to offer the best possible experience you can have when editing T4 files.&lt;/p&gt;  &lt;p&gt;As a result of this most 3rd party extensions out there in the VS Gallery should be compatible with Visual T4 thus improving your productivity even when writing T4 code.&lt;/p&gt;  &lt;p&gt;You can see below the very handy &lt;a href="http://visualstudiogallery.msdn.microsoft.com/en-us/dc06b54c-b6c4-4cf5-8203-a09c6979e881" target="_blank"&gt;Quick Add Reference&lt;/a&gt; in action, working from inside a C# embedded code block:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_-aHmLaAmtoU/TNebuJNru9I/AAAAAAAAABc/Fdb8yBPbPUM/s1600-h/visualt4-015.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="visualt4-01" border="0" alt="visualt4-01" src="http://lh4.ggpht.com/_-aHmLaAmtoU/TNebvo2mruI/AAAAAAAAABg/wp-dxeOCckc/visualt4-01_thumb3.png?imgmax=800" width="458" height="475" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Or the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/en-us/55c24bf1-2636-4f94-831d-28db8505ce00" target="_blank"&gt;Regex Editor&lt;/a&gt;, used to edit a regular expression inside a C# code block:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_-aHmLaAmtoU/TNebx05zzMI/AAAAAAAAABk/EnfS-sn8uY0/s1600-h/visualt4-024.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="visualt4-02" border="0" alt="visualt4-02" src="http://lh5.ggpht.com/_-aHmLaAmtoU/TNebzM6R-kI/AAAAAAAAABo/TsU0IrQ6Jr8/visualt4-02_thumb2.png?imgmax=800" width="658" height="429" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The beta 1 bits are pretty stable although there are a few nasty issues that we are working on fixing for beta 2 but we didn’t want to hold on releasing the bits as there were LOTS of you interested in early trying them.&lt;/p&gt;  &lt;p&gt;PLEASE share your feedback with us: bugs, suggestions, etc., everything is welcomed and we try to reply to every email we receive. You can follow us &lt;a href="http://twitter.com/visualt4" target="_blank"&gt;@visualt4&lt;/a&gt;, reach us at &lt;a href="mailto:visualt4@clariusconsulting.net"&gt;visualt4@clariusconsulting.net&lt;/a&gt;, or use the comments on this posts, or the &lt;a href="http://goo.gl/TNtC7" target="_blank"&gt;QA section in the VS Gallery entry&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/MjpOr_hXZ5s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/MjpOr_hXZ5s/visual-t4-beta-1-is-now-available.html</link><author>noreply@blogger.com (Visual T4)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_-aHmLaAmtoU/TNebvo2mruI/AAAAAAAAABg/wp-dxeOCckc/s72-c/visualt4-01_thumb3.png?imgmax=800" height="72" width="72" /><thr:total>13</thr:total><feedburner:origLink>http://blog.visualt4.com/2010/11/visual-t4-beta-1-is-now-available.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-4662955330743000712</guid><pubDate>Sat, 21 Aug 2010 06:40:00 +0000</pubDate><atom:updated>2010-08-20T23:40:48.754-07:00</atom:updated><title>Visual T4 for Visual Studio 2010</title><description>&lt;p&gt;It’s been a long time since our last post. I just wanted to let you know about the amazing progress we’ve been making on Visual T4 for VS2010. What’s new in short? A major overhaul to take full advantage of all the benefits of the brand new WPF-based core text editor as well as the new language services to provide the absolutely unique and long-time praised Intellisense integration. &lt;/p&gt;  &lt;p&gt;We’ll go into the details on another post, but here’s a bunch of screenshots to get you excited, using the ADO.NET C# POCO Entity Generator templates.&lt;/p&gt;  &lt;p&gt;Colors honor your favorite C# editor settings:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_hftGKBauGHI/TG90pbxh0CI/AAAAAAAAD7U/1V8OIBtq5Zg/s1600-h/image%5B4%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_hftGKBauGHI/TG90qRyoXEI/AAAAAAAAD7Y/wErLNw8jqr4/image_thumb%5B2%5D.png?imgmax=800" width="644" height="443" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_hftGKBauGHI/TG90qxTdjxI/AAAAAAAAD7c/fx-dXJrrKE4/s1600-h/image%5B9%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hftGKBauGHI/TG90r5i1k6I/AAAAAAAAD7g/-MrypXl7bzM/image_thumb%5B5%5D.png?imgmax=800" width="644" height="443" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Tooltips as usual in C#:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_hftGKBauGHI/TG90sZ00paI/AAAAAAAAD7k/ziZ7Kas1BIM/s1600-h/image%5B14%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_hftGKBauGHI/TG90tGFxxwI/AAAAAAAAD7o/MWJn3hJaOhw/image_thumb%5B8%5D.png?imgmax=800" width="644" height="53" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Intellisense on APIs as usual in C#:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_hftGKBauGHI/TG90tZXyu6I/AAAAAAAAD7s/uS1HHAaOQek/s1600-h/image%5B19%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_hftGKBauGHI/TG90uJFP-TI/AAAAAAAAD7w/9QLqZfEHxRg/image_thumb%5B11%5D.png?imgmax=800" width="644" height="154" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Parameter info as usual in C# code :)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_hftGKBauGHI/TG90vDZy-TI/AAAAAAAAD70/TpcV8nLsvqA/s1600-h/image%5B27%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_hftGKBauGHI/TG90vvghGXI/AAAAAAAAD74/-_TjQU0Zgvc/image_thumb%5B15%5D.png?imgmax=800" width="644" height="131" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Pretty good indenting!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_hftGKBauGHI/TG90wsXuXtI/AAAAAAAAD78/pXGa20r7Klc/s1600-h/image%5B32%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_hftGKBauGHI/TG90xTc046I/AAAAAAAAD8A/8AweM3ChxcY/image_thumb%5B18%5D.png?imgmax=800" width="644" height="474" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Full support for VERY complex includes! (the EF one has 2200+ lines)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_hftGKBauGHI/TG90yN9xcRI/AAAAAAAAD8E/H1uCWZmBFDA/s1600-h/image%5B38%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_hftGKBauGHI/TG90zG4K_sI/AAAAAAAAD8I/6o89MFMUrcw/image_thumb%5B22%5D.png?imgmax=800" width="644" height="179" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Full T4 directives intellisense with tooltips, as you’d expect:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_hftGKBauGHI/TG90z9jIj2I/AAAAAAAAD8M/pEASzqMjFH8/s1600-h/image%5B43%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hftGKBauGHI/TG900jdew4I/AAAAAAAAD8Q/eEktOfli2cM/image_thumb%5B25%5D.png?imgmax=800" width="644" height="86" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Can add arbitrary assemblies an get their intellisense too:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_hftGKBauGHI/TG901H0tlAI/AAAAAAAAD8U/Zmk_oJJZBk8/s1600-h/image%5B48%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hftGKBauGHI/TG902iIuW1I/AAAAAAAAD8Y/vmsZvceOjWE/image_thumb%5B28%5D.png?imgmax=800" width="644" height="214" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Can build any LINQ query you fancy with full intellisense:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_hftGKBauGHI/TG903Jyo1QI/AAAAAAAAD8c/WUNxFDWDneE/s1600-h/image%5B53%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hftGKBauGHI/TG9031KNEgI/AAAAAAAAD8g/uaZqZOUBr6w/image_thumb%5B31%5D.png?imgmax=800" width="644" height="287" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Use your favorite code snippets as usual in C#:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_hftGKBauGHI/TG904vLT1BI/AAAAAAAAD8k/Q1qnPHCGXkQ/s1600-h/image%5B58%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hftGKBauGHI/TG905IX4mDI/AAAAAAAAD8o/DAzx_zeICmI/image_thumb%5B34%5D.png?imgmax=800" width="644" height="263" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;With even full anonymous types support:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_hftGKBauGHI/TG905kTpazI/AAAAAAAAD8s/9A3_K4BKFNM/s1600-h/image%5B63%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_hftGKBauGHI/TG906eXxNeI/AAAAAAAAD8w/_UIn6EI47M8/image_thumb%5B37%5D.png?imgmax=800" width="644" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And Intellisense of course:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_hftGKBauGHI/TG9066LjFHI/AAAAAAAAD80/CYv_iRnKejo/s1600-h/image%5B68%5D.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_hftGKBauGHI/TG9072g1ZUI/AAAAAAAAD84/rxh46jG3THY/image_thumb%5B40%5D.png?imgmax=800" width="644" height="329" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;A BIG kudos to the Visual T4 team for such an amazing integration into VS2010. We’ll be sharing the bits more broadly very soon. We’re beta testing it at this very moment.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/DMtvXrJpsZI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/DMtvXrJpsZI/visual-t4-for-visual-studio-2010.html</link><author>noreply@blogger.com (kzu)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_hftGKBauGHI/TG90qRyoXEI/AAAAAAAAD7Y/wErLNw8jqr4/s72-c/image_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>10</thr:total><feedburner:origLink>http://blog.visualt4.com/2010/08/visual-t4-for-visual-studio-2010.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-9619739593954952</guid><pubDate>Mon, 29 Jun 2009 18:24:00 +0000</pubDate><atom:updated>2009-06-29T11:39:23.302-07:00</atom:updated><title>Buy Visual T4 Pro, Get Free Pro ASP.NET MVC Book!</title><description>&lt;p&gt;Yes, the best T4 Editor meets the best ASP.NET MVC book.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.amazon.com/Professional-ASP-NET-MVC-Wrox-Programmer/dp/0470384611/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1246064357&amp;amp;sr=8-2" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="AspNetMvcFreeBook" border="0" alt="AspNetMvcFreeBook" src="http://lh6.ggpht.com/_-aHmLaAmtoU/SkkGx2ZdoGI/AAAAAAAAABQ/XpcKqSjKibQ/AspNetMvcFreeBook3.png?imgmax=800" width="167" height="208" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;If you’re into ASP.NET MVC and want to play and customize the MVC T4 templates with wonderful support getting full Preview, IntelliSense, syntax coloring and more for both T4 and C# embedded code this deal is for you!&lt;/p&gt;  &lt;p&gt;Buy &lt;a href="http://www.visualt4.com/buy.html" target="_blank"&gt;here&lt;/a&gt; the Visual T4 Editor Professional and you will get the book for free.&lt;/p&gt;  &lt;p&gt;This promotion is only valid till July, 3rd, 2009&amp;#160; or until we ran out of our 100 books stock, whatever comes first.&lt;/p&gt;  &lt;p&gt;As we know no one wants to wait a week for a book &lt;strong&gt;we will ship it using a 2nd-day service&lt;/strong&gt; to get you the book really quick.&lt;/p&gt;  &lt;p&gt;Please note we can only ship to an US address, sorry.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/GWowha1mAC4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/GWowha1mAC4/buy-visual-t4-pro-get-free-pro-aspnet.html</link><author>noreply@blogger.com (Visual T4)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_-aHmLaAmtoU/SkkGx2ZdoGI/AAAAAAAAABQ/XpcKqSjKibQ/s72-c/AspNetMvcFreeBook3.png?imgmax=800" height="72" width="72" /><thr:total>7</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/06/buy-visual-t4-pro-get-free-pro-aspnet.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-6700873925718169123</guid><pubDate>Tue, 21 Apr 2009 01:02:00 +0000</pubDate><atom:updated>2009-04-20T18:04:52.253-07:00</atom:updated><title>Visual T4 in the news!</title><description>&lt;p&gt;Our Visual T4 products continue to be mentioned by pretty much everyone out there working with T4. You already know our tools &lt;a href="http://blog.visualt4.com/2009/03/visual-t4-mix09.html" target="_blank"&gt;were used in MIX09&lt;/a&gt; (besides other major conferences in the past) and that &lt;a href="http://blog.visualt4.com/2009/03/visual-web-developer-team-ms-highly.html" target="_blank"&gt;pretty big teams at Microsoft recommend it&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We did google a bit and these are the most “remarkable” mentions we’re getting (it’s just great to see we have built the “standard” tool for editing T4 files!):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.hanselman.com/blog/" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;Scott Hanlseman&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt; (&lt;em&gt;Principal Program Manager, Microsoft) on &lt;/em&gt;&lt;a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx" target="_blank"&gt;&lt;em&gt;T4 (Text Template Transformation Toolkit) Code Generation - Best Kept Visual Studio Secret&lt;/em&gt;&lt;/a&gt;&lt;em&gt;:&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;&amp;quot;if you want really get the most out of T4, first, head over to Clarius Consulting and get their &amp;quot;&lt;a href="http://www.visualt4.com" target="_blank"&gt;T4 Editor Community Edition&lt;/a&gt;.&amp;quot; That'll get you some basic coloring. They have a pay version that gets you more if you want.&amp;quot;&lt;/em&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;   &lt;em&gt;&lt;/em&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://www.olegsych.com" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;Oleg Sych&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;, uses &lt;a href="http://www.visualt4.com" target="_blank"&gt;Visual T4 Editor&lt;/a&gt; in his must-read &lt;a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/" target="_blank"&gt;series of T4 articles&lt;/a&gt; mentions:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“…Instead, the approach used by Clarius in their implementation of this directive included with &lt;/em&gt;&lt;a href="http://www.visualt4.com"&gt;&lt;em&gt;T4 Editor&lt;/em&gt;&lt;/a&gt;&lt;em&gt; relies on &lt;/em&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.aspx"&gt;&lt;em&gt;CallContext&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, is a lot more robust and elegant…”&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;“…Text editing and debugging support for T4 templates is currently rather limited. &lt;/em&gt;&lt;a href="http://www.t4editor.net/"&gt;&lt;em&gt;T4 Editor&lt;/em&gt;&lt;/a&gt;&lt;em&gt; (a free download) from Clarius Consulting provides IntelliSense and syntax highlighting in Visual Studio text editor for .tt files…”        &lt;br /&gt;        &lt;br /&gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.olegsych.com" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;Miguel de Icaza&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;, on &lt;a href="http://tirania.org/blog/archive/2009/Mar-10.html" target="_blank"&gt;Mono's Text Template Transformation Toolkit (T4)&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“To my surprise T4 thing is wildly used by lots of people. &lt;/em&gt;&lt;a href="http://www.clariusconsulting.net/blogs/kzu/"&gt;&lt;em&gt;Daniel Cazzulino&lt;/em&gt;&lt;/a&gt;&lt;em&gt;'s &lt;/em&gt;&lt;a href="http://www.clariusconsulting.net/"&gt;&lt;em&gt;company&lt;/em&gt;&lt;/a&gt;&lt;em&gt; has a product just to improve Visual Studio's support for editing .tt files.”        &lt;br /&gt;        &lt;br /&gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;&lt;a href="http://reddevnews.com/" target="_blank"&gt;Redmond Developer News&lt;/a&gt;&lt;/strong&gt;&lt;/font&gt; , on &lt;a href="http://reddevnews.com/news/devnews/article.aspx?editorialsid=1199" target="_blank"&gt;Code Generation Made Easy&lt;/a&gt; : &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;&amp;quot;There are a lot of tools out there that do code generation,&amp;quot; Conery says. &amp;quot;Great tools like CodeSmith and Clarius Consulting's T4 Editor”        &lt;br /&gt;        &lt;br /&gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/garethj/" target="_blank"&gt;Gareth Jones&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;font size="2"&gt;&lt;em&gt;(Visual Studio team member, Microsoft)&lt;/em&gt;&lt;/font&gt;&lt;/font&gt; , on &lt;a href="http://blogs.msdn.com/garethj/archive/2009/02/04/clarius-take-t4-editing-to-the-next-level.aspx" target="_blank"&gt;Clarius take T4 editing to the next level&lt;/a&gt; : &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“…I see that &lt;/em&gt;&lt;a href="http://www.clariusconsulting.net/"&gt;&lt;em&gt;Clarius&lt;img src="http://i.ixnp.com/images/v3.72/t.gif" /&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt; have now got to an alpha stage for the next stage of their T4 editing toolset.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;As well as their &lt;/em&gt;&lt;em&gt;Community Edition &lt;/em&gt;&lt;em&gt;and Pro Edition, they're now going to offer a full-featured code generation environment they're calling Visual T4 Code Generator, including tight integration with server explorer, database tables and XML as well as a multi-file generation implementation out of the box and &lt;/em&gt;&lt;a href="http://www.visualt4.com/features.html"&gt;&lt;em&gt;lots more beside&lt;img src="http://i.ixnp.com/images/v3.72/t.gif" /&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;…”        &lt;br /&gt;        &lt;br /&gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/pedrosilva" target="_blank"&gt;Pedro Silva&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;font size="2"&gt;&lt;em&gt;(Visual Studio team member, Microsoft)&lt;/em&gt;&lt;/font&gt;&lt;/font&gt; , on &lt;a href="http://blogs.msdn.com/pedrosilva/archive/2007/10/18/t4-editor-beta-released.aspx" target="_blank"&gt;T4 Editor Beta Released&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“The folks at Clarius have an update to their T4 template editor. They're now in Beta. It's a very useful editor for anyone doing large amounts of T4 template editing with good factoring of template code vs script and color coding of keywords.”&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;&lt;a href="http://msmvps.com/blogs/kathleen" target="_blank"&gt;Kathleen Dollard&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;font size="2"&gt;&lt;em&gt;(Microsoft MVP)&lt;/em&gt;&lt;/font&gt;&lt;/font&gt; , on &lt;a href="http://msmvps.com/blogs/kathleen/archive/2009/03/17/what-s-wrong-with-t4.aspx" target="_blank"&gt;What’s Wrong with T4?&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“There’s good news here. Clarius provides a colorizing editor as a community edition to get you started. If you want fancier features, their main product is just $100”&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/lXzHbrry26M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/lXzHbrry26M/visual-t4-in-news.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/04/visual-t4-in-news.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-2659556014445225569</guid><pubDate>Tue, 21 Apr 2009 00:47:00 +0000</pubDate><atom:updated>2009-04-20T17:47:34.815-07:00</atom:updated><title>Hanselminutes on Code Generation</title><description>&lt;p&gt;In case you missed this (as we did) &lt;a href="www.hanselman.com" target="_blank"&gt;Scott&lt;/a&gt; interviews Kathleen Dollard (Microsoft MVP) on code generation in .Net and Visual Studio.&lt;/p&gt;  &lt;p&gt;It’s an interesting chat on the past and current state of code gen, with emphasis on T4. You can listen to the podcast &lt;a href="http://www.hanselminutes.com/default.aspx?showID=170" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Make sure you don’t miss the audio @ 19m:43s where &lt;a href="http://www.visualt4.com" target="_blank"&gt;Clarius Visual T4 Editor&lt;/a&gt; is recommended if you are into serious editing of T4 templates :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/tsqrpHC3sSU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/tsqrpHC3sSU/hanselminutes-on-code-generation.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/04/hanselminutes-on-code-generation.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-3644353008065763656</guid><pubDate>Fri, 27 Mar 2009 02:46:00 +0000</pubDate><atom:updated>2009-03-26T19:47:25.029-07:00</atom:updated><title>The process of building a Code Generation template</title><description>&lt;p&gt;More often than not, you’ll have several related classes and you’ll want to turn them into generated code. There is a process I like to use to make a generation template that’s based on this idea. You can also use the process even if you don’t have the classes, by building them manually.&lt;/p&gt;  &lt;p&gt;First, you’ll need a class. For example, we’re going to use generation to create a strongly type representation of a directory structure and files on disk. In the example, these files will be configuration files spread throughout a few directories, but we’ll open them as simple strings to make the sample easier. Let’s look at the code:&lt;/p&gt;  &lt;pre class="brush: c-sharp;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;namespace MyCompany.MyProduct&lt;br /&gt;{&lt;br /&gt;    class Configuration&lt;br /&gt;    {&lt;br /&gt;        private string baseDir = &amp;quot;Configuration&amp;quot;;&lt;br /&gt;&lt;br /&gt;        public Configuration(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, &amp;quot;\\Configuration&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public Network Network&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return new Network(baseDir);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class Network&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public Network(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, &amp;quot;\\Network&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string ProxiesConfig&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, &amp;quot;\\Proxies.Config&amp;quot;);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, &amp;quot;\\Proxies.Config&amp;quot;), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string HostsConfig&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, &amp;quot;\\Hosts.Config&amp;quot;);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, &amp;quot;\\Hosts.Config&amp;quot;), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class Security&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public Security(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, &amp;quot;\\Security&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string RolesConfig&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, &amp;quot;\\Roles.Config&amp;quot;);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, &amp;quot;\\Roles.Config&amp;quot;), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Notice that this code already has a “generated” look and feel. The idea is to create a Configuration object with the base path for configuration, and to go down from there to all the configuration items. Network and Security will be directories within Configuration, and the other properties will refer to files in the directories. Notice also that at this point it’s not very important to have complete classes. A rough layout is enough.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The next step is to find varying parts. This is really simple: variables will generally be present as constants or as variable properties. Constants is far more common. In this step, we’ll replace the constants with representative code blocks:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;    class Configuration&lt;br /&gt;    {&lt;br /&gt;        private string baseDir = &amp;lt;#= baseDirectoryName #&amp;gt;;&lt;br /&gt;&lt;br /&gt;        public Configuration(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, “&amp;lt;#= baseDirectoryPath #&amp;gt;”);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public Network Network&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return new Network(baseDir);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class Network&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public Network(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, “&amp;lt;#= baseDirectoryPath #&amp;gt;”);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string ProxiesConfig&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string HostsConfig&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Then we’ll also replace the varying property names (and class and method names if necessary) with code blocks too:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;    class &amp;lt;#= baseDirectoryName #&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        private string baseDir = &amp;lt;#= baseDirectoryName #&amp;gt;;&lt;br /&gt;&lt;br /&gt;        public Configuration(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, “&amp;lt;#= baseDirectoryPath #&amp;gt;”);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public &amp;lt;#= childDirectoryName #&amp;gt; &amp;lt;#= childDirectoryName #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return new &amp;lt;#= childDirectoryName #&amp;gt;(baseDir);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class &amp;lt;#= baseDirectoryName #&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public &amp;lt;#= baseDirectoryName #&amp;gt;(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, “&amp;lt;#= baseDirectoryName #&amp;gt;”);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string &amp;lt;#= configFileName #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string &amp;lt;#= configFileName #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;At this point, you should have some duplication. The next step is to remove that duplication by looping through duplicated constructs:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;&amp;lt;#&lt;br /&gt;  for (int classes = 0; classes &amp;lt; n; classes++)&lt;br /&gt;  {&lt;br /&gt;#&amp;gt;&lt;br /&gt;    class &amp;lt;#= baseDirectoryName #&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public &amp;lt;#= baseDirectoryName #&amp;gt;(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, “&amp;lt;#= baseDirectoryName #&amp;gt;”);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&amp;lt;#&lt;br /&gt;      for (int props = 0; props &amp;lt; n; props++)&lt;br /&gt;      {&lt;br /&gt;#&amp;gt;&lt;br /&gt;        public string &amp;lt;#= configFileName #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&amp;lt;#&lt;br /&gt;      }&lt;br /&gt;#&amp;gt;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;#&lt;br /&gt;  }&lt;br /&gt;#&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You should also add whatever’s left behind (in this case, the “directory” properties:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;&amp;lt;#&lt;br /&gt;  for (int classes = 0; classes &amp;lt; n; classes++)&lt;br /&gt;  {&lt;br /&gt;#&amp;gt;&lt;br /&gt;    class &amp;lt;#= baseDirectoryName #&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public &amp;lt;#= baseDirectoryName #&amp;gt;(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, “&amp;lt;#= baseDirectoryName #&amp;gt;”);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&amp;lt;#&lt;br /&gt;      for (int childClasses = 0; childClasses &amp;lt; n; childClasses++)&lt;br /&gt;      {&lt;br /&gt;#&amp;gt;&lt;br /&gt;        public &amp;lt;#= childDirectoryName #&amp;gt; &amp;lt;#= childDirectoryName #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return new &amp;lt;#= childDirectoryName #&amp;gt;(baseDir);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&amp;lt;#&lt;br /&gt;      }&lt;br /&gt;#&amp;gt;&lt;br /&gt;&amp;lt;#&lt;br /&gt;      for (int props = 0; props &amp;lt; n; props++)&lt;br /&gt;      {&lt;br /&gt;#&amp;gt;&lt;br /&gt;        public string &amp;lt;#= configFileName #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, “&amp;lt;#= configFileName #&amp;gt;”), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&amp;lt;#&lt;br /&gt;      }&lt;br /&gt;#&amp;gt;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;#&lt;br /&gt;  }&lt;br /&gt;#&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;At this point, you should have a pretty good skeleton. The point now is to make it work:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;&amp;lt;#&lt;br /&gt;  foreach(string directory in Directory.GetDirectories(&amp;quot;myconfigurationdir&amp;quot;))&lt;br /&gt;  {&lt;br /&gt;#&amp;gt;&lt;br /&gt;    class &amp;lt;#= directory #&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public &amp;lt;#= directory #&amp;gt;(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, &amp;quot;&amp;lt;#= directory #&amp;gt;&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&amp;lt;#&lt;br /&gt;      foreach (string childDirectory in Directory.GetDirectories(directory))&lt;br /&gt;      {&lt;br /&gt;#&amp;gt;&lt;br /&gt;        public Network &amp;lt;#= childDirectory #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return new &amp;lt;#= childDirectory #&amp;gt;(baseDir);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&amp;lt;#&lt;br /&gt;      }&lt;br /&gt;#&amp;gt;&lt;br /&gt;&amp;lt;#&lt;br /&gt;      foreach (string file in Directory.GetFiles(directory))&lt;br /&gt;      {&lt;br /&gt;#&amp;gt;&lt;br /&gt;        public string &amp;lt;#= file #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, &amp;quot;&amp;lt;#= file #&amp;gt;&amp;quot;);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, &amp;quot;&amp;lt;#= file #&amp;gt;&amp;quot;), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&amp;lt;#&lt;br /&gt;      }&lt;br /&gt;#&amp;gt;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;#&lt;br /&gt;  }&lt;br /&gt;#&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;At this point you should be added any imports that are needed for the generation code to work (System.IO in this case). You may also need to separate processes in methods, as to make them recursive. For instance, our classes need to be generated for each directory in the hierarchy. Finally, you must solve generation-specific problems. For instance, this generation will probably have many invalid class and property names (“Proxies.Config” is not a valid class name). You can change that by using the CleanName procedure that we already reviewed in this blog. The result will look something like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;&amp;lt;#&lt;br /&gt;  GenerateClass(&amp;quot;myconfigdir&amp;quot;);&lt;br /&gt;#&amp;gt;&lt;br /&gt;&amp;lt;#+&lt;br /&gt;void GenerateClass(string directoryName)&lt;br /&gt;{&lt;br /&gt;  foreach(string directory in Directory.GetDirectories(directoryName))&lt;br /&gt;  {&lt;br /&gt;#&amp;gt;&lt;br /&gt;    class &amp;lt;#= CleanName(directory) #&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        private string baseDir;&lt;br /&gt;&lt;br /&gt;        public &amp;lt;#= CleanName(directory) #&amp;gt;(string baseDir)&lt;br /&gt;        {&lt;br /&gt;            this.baseDir = string.Concat(baseDir, &amp;quot;&amp;lt;#= directory #&amp;gt;&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&amp;lt;#+&lt;br /&gt;      foreach (string childDirectory in Directory.GetDirectories(directory))&lt;br /&gt;      {&lt;br /&gt;#&amp;gt;&lt;br /&gt;        public &amp;lt;#= CleanName(childDirectory) #&amp;gt; &amp;lt;#= CleanName(childDirectory) #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return new &amp;lt;#= CleanName(childDirectory) #&amp;gt;(baseDir);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&amp;lt;#+&lt;br /&gt;      }&lt;br /&gt;#&amp;gt;&lt;br /&gt;&amp;lt;#+&lt;br /&gt;      foreach (string file in Directory.GetFiles(directory))&lt;br /&gt;      {&lt;br /&gt;#&amp;gt;&lt;br /&gt;        public string &amp;lt;#= CleanName(file) #&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return File.ReadAllText(string.Concat(baseDir, &amp;quot;&amp;lt;#= file #&amp;gt;&amp;quot;);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                File.WriteAllText(string.Concat(baseDir, &amp;quot;&amp;lt;#= file #&amp;gt;&amp;quot;), value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&amp;lt;#+&lt;br /&gt;      }&lt;br /&gt;#&amp;gt;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;#+&lt;br /&gt;    GenerateClass(directory);&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;string CleanName(string)&lt;br /&gt;&lt;br /&gt;   {&lt;br /&gt;&lt;br /&gt;	//some code cleaning here&lt;br /&gt;&lt;br /&gt;	}&lt;br /&gt;#&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The final step is to separate the code into modules. For instance, you can put the CleanName procedure in an include T4 file to be used as a helper, put the header in a “main” T4 and the methods in generation T4 files, separate the properties into its own include, or whatever feels good to you.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;--&lt;br /&gt;  &lt;br /&gt;&lt;em&gt;Written by Joaquin, joj AT clariusconsulting DOT net. Disclaimer: opinions expressed in this post are my own and not necessarily reflect those of Clarius Consulting.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/x71vqN9S6Ss" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/x71vqN9S6Ss/process-of-building-code-generation.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>3</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/process-of-building-code-generation.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-7453714218188783020</guid><pubDate>Tue, 24 Mar 2009 05:06:00 +0000</pubDate><atom:updated>2009-03-23T22:06:14.492-07:00</atom:updated><title>Visual T4 @ MIX09</title><description>&lt;p&gt;We’ve been catching up on web techs watching MIX09 videos and guess what…?&lt;/p&gt;  &lt;p&gt;Scott Hanselman in his &lt;a href="http://videos.visitmix.com/MIX09/T49F" target="_blank"&gt;&lt;em&gt;File|New -&amp;gt; Company: Creating NerdDinner.com with Microsoft ASP.NET Model View Controller (MVC)&lt;/em&gt;&lt;/a&gt; and Phil Haack in his &lt;a href="http://videos.visitmix.com/MIX09/T44F" target="_blank"&gt;&lt;em&gt;Microsoft ASP.NET Model View Controller (MVC): Ninja on Fire Black Belt Tips&lt;/em&gt;&lt;/a&gt; talks both mention the Clarius &lt;a href="http://www.visualt4.com" target="_blank"&gt;Visual T4 Editor&lt;/a&gt; for editing T4 templates!&lt;/p&gt;  &lt;p&gt;Here is a screenshot of Phil, on stage, using the &lt;a href="http://www.visualt4.com" target="_blank"&gt;Visual T4 Editor&lt;/a&gt; Professional edition:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_-aHmLaAmtoU/SchqPnCGglI/AAAAAAAAABE/4pxODZkkW7s/s1600-h/VisualT4Mix092.png"&gt;&lt;img title="VisualT4Mix09" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="174" alt="VisualT4Mix09" src="http://lh3.ggpht.com/_-aHmLaAmtoU/SchqRZ_pPPI/AAAAAAAAABM/Bo9x8UEnL68/VisualT4Mix09_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Good to see Visual T4 being used everywhere!!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/G2352lRpnp0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/G2352lRpnp0/visual-t4-mix09.html</link><author>noreply@blogger.com (Visual T4)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_-aHmLaAmtoU/SchqRZ_pPPI/AAAAAAAAABM/Bo9x8UEnL68/s72-c/VisualT4Mix09_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/visual-t4-mix09.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-3343347843976818214</guid><pubDate>Tue, 24 Mar 2009 04:53:00 +0000</pubDate><atom:updated>2009-03-23T22:04:37.416-07:00</atom:updated><title>NHibernate: Why override GetHashCode and Equals?</title><description>&lt;p&gt;When using NHibernate collections, or when comparing two objects that are configured via NHibernate configuration, NHibernate code will use the Equals and GetHashCode methods in the class. It is very important to implement this methods in a way that will make two different entities return different values and to identical entities return identical values. That’s the only condition. The value doesn’t need to be related to anything in the table at all as long as it passes that test. This is both easy and hard. Let me show you why.&lt;/p&gt;  &lt;p&gt;The point here is to always generate a value that will represent a row in the table. In a normal table, any candidate key (that is, a unique index or a primary key) will serve this role. In the samples that come with &lt;a href="http://www.visualt4.com" target="_blank"&gt;Visual T4 Editor Professional&lt;/a&gt; edition we use the primary key to generate these methods:&lt;/p&gt;  &lt;pre class="brush: c-sharp;"&gt;        public override int GetHashCode()&lt;br /&gt;        {&lt;br /&gt;            int hashCode = 0;&lt;br /&gt;            hashCode = hashCode ^ CustomerID.GetHashCode();&lt;br /&gt;            return hashCode;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        public override bool Equals(object obj)&lt;br /&gt;        {&lt;br /&gt;            Customers toCompare = obj as Customers;&lt;br /&gt;            if (toCompare == null)&lt;br /&gt;            {&lt;br /&gt;                return false;&lt;br /&gt;            }&lt;br /&gt;            if (this.CustomerID != toCompare.CustomerID)&lt;br /&gt;            {&lt;br /&gt;                return false;&lt;br /&gt;            }&lt;br /&gt;            return true;&lt;br /&gt;        }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The Equals method is fairly simple to override. Just compare keys, and if everything matches return true. GetHashCode is a little different. You must return an integer value tailored to the needs of the two rules. For the sample, we have chosen to use xor to compare, due to a high success rate. For production code, you should choose to “shift and or” or to concatenate and get the hash code of the string. Both methods will give you a 100% success rate, on varying levels of complexity and performance.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There is an additional problem here, specially for code generation: if you have a transient object (that is, one that is not yet saved to the database) and identity value will always be a bad choice. The problem is that until NHibernate saves the object to the database, the value of the identity (or primary key, depending on configuration) will be the default value for the datatype (0 in this case). Hence, two unsaved values will be equal. Although this is technically correct (unsaved values may be considered “null” for some purposes) it is highly impractical.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In this case, the best solution is to take an alternate key (an unique non-null key) and use that for the comparison. As long as the user actually fills that value when constructing the object, everything should be fine. A code generator may find a candidate key and use it. It will not, however, be able to know if this candidate key will be filled when needed. As a default solution both primary key and a candidate key may work. As a definitive solution, you should use the class knowing that you may run into this issue and manually override (as explained in Extending Code Generation with Partial Classes and Inheritance) when needed. To be 100% sure, you should always create the GetHashCode manually, and override equals with this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;        public override bool Equals(object obj)&lt;br /&gt;        {&lt;br /&gt;            Customers toCompare = obj as Customers;&lt;br /&gt;            if (toCompare == null)&lt;br /&gt;            {&lt;br /&gt;                return false;&lt;br /&gt;            }&lt;br /&gt;            return (this.GetHashCode() != toCompare.GetHashCode())&lt;br /&gt;        }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;--&lt;br /&gt;  &lt;br /&gt;&lt;em&gt;Written by Joaquin, joj AT clariusconsulting DOT net. Disclaimer: opinions expressed in this post are my own and not necessarily reflect those of Clarius Consulting.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/yiBBMGYWkTI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/yiBBMGYWkTI/nhibernate-why-override-gethashcode-and.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>3</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/nhibernate-why-override-gethashcode-and.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-8515905034962342211</guid><pubDate>Tue, 24 Mar 2009 04:41:00 +0000</pubDate><atom:updated>2009-03-23T21:48:02.769-07:00</atom:updated><title>Transforming Type Names</title><description>There are many situations in code generation where you may need to render the name of a Type in the generated file. For instance, you may have a method somewhere that translates a data type in a specific format to a Type, and then you want to render that type.  The easy way to do it is obviously &lt;pre class="brush: c-sharp;"&gt;&amp;#160;&amp;#160;&amp;#160; Type.ToString() &lt;/pre&gt;&lt;br /&gt;but this has many drawbacks. The first problem, and this is mostly aesthetic, is that standard types like “int”, “long”, “double”, etc will be rendered as “System.Int32”, “System.Int64”, “System.Double”. Although this will work, the resulting code will have a “generated” look and feel. Your code should always be as “not-generated” as possible. That will make it easier to read and debug.&lt;br /&gt;&lt;br /&gt;The second problem is that there are types that will simply not translate to your preferred language easily. For instance, “List&amp;lt;string&amp;gt;” will be translated as “System.Collections.Generic.List’1[System.String]”. There is no way for that text to be useful in a generation context!&lt;br /&gt;&lt;br /&gt;There are a few ways to work around this. You may code a few methods that will translate from the Type to your language. This is not a trivial task, but there are a few implementations readily available. For instance, the class ContractNameServices.cs in MEF (&lt;a href="http://www.codeplex.com/MEF/SourceControl/changeset/view/26383#370431)"&gt;http://www.codeplex.com/MEF/SourceControl/changeset/view/26383#370431)&lt;/a&gt; has a method named GetDefaultContractName which does just that, and it is very cleanly implemented.&lt;br /&gt;&lt;br /&gt;The easiest way is to use a CodeDomProvider for your language. The following few lines of code illustrate this concept:&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;CodeTypeReferenceExpression type = new CodeTypeReferenceExpression(typeof(System.Collections.Generic.List&amp;lt;float&amp;gt;));&lt;br /&gt;CodeDomProvider csProvider = Microsoft.CSharp.CSharpCodeProvider.CreateProvider(&amp;quot;C#&amp;quot;);&lt;br /&gt;CodeDomProvider vbProvider = Microsoft.VisualBasic.VBCodeProvider.CreateProvider(&amp;quot;VB&amp;quot;);&lt;br /&gt;StringWriter writer = new StringWriter();&lt;br /&gt;csProvider.GenerateCodeFromExpression(type, writer, new CodeGeneratorOptions());&lt;br /&gt;writer.Write(writer.NewLine);&lt;br /&gt;vbProvider.GenerateCodeFromExpression(type, writer, new CodeGeneratorOptions());&lt;br /&gt;Console.WriteLine(writer.ToString());&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The output of this code will be:&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;System.Collections.Generic.List&amp;lt;float&amp;gt;&lt;br /&gt;System.Collections.Generic.List(Of Single) &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;which is both useful and language independent at the same time.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;--&lt;br /&gt;  &lt;br /&gt;&lt;em&gt;Written by Joaquin, joj AT clariusconsulting DOT net. Disclaimer: opinions expressed in this post are my own and not necessarily reflect those of Clarius Consulting.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/5jZdBgBrGdQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/5jZdBgBrGdQ/transforming-type-names.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/transforming-type-names.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-6463435986132992665</guid><pubDate>Wed, 18 Mar 2009 17:40:00 +0000</pubDate><atom:updated>2009-03-18T10:40:51.173-07:00</atom:updated><title>Visual Web Developer Team @ MS highly highly recommends Visual T4 Editor</title><description>&lt;p&gt;We really love each time we see our Visual T4 products used inside Microsoft.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/webdevtools" target="_blank"&gt;The Visual Web Developer Team&lt;/a&gt; in&amp;#160; &lt;a href="http://blogs.msdn.com/webdevtools/archive/2009/01/29/t4-templates-a-quick-start-guide-for-asp-net-mvc-developers.aspx" target="_blank"&gt;T4 Templates: A Quick-Start Guide for ASP.NET MVC Developers&lt;/a&gt; says:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;If you open a .tt file inside Visual Studio, you may notice they look a bit flat – like a wall of black text.&amp;#160; We &lt;font size="4"&gt;&lt;/font&gt;&lt;span style="font-size: 18px; color: red; background-color: yellow"&gt;highly highly recommend&lt;/span&gt; you download &lt;a href="http://www.visualt4.com"&gt;T4 Editor&lt;/a&gt;, an add-on to Visual Studio made by &lt;a href="http://www.clariusconsulting.net/"&gt;Clarius Consulting&lt;/a&gt;, to provide you with syntax highlighting and some basic T4 statement completion.&amp;#160; They have a free version called the ‘Community Edition’, as well as a much more powerful ‘Professional Edition’ – check out the &lt;a href="http://www.visualt4.com/features.html"&gt;feature comparison&lt;/a&gt; if you are interested.&amp;#160; This add-on really makes a big difference in template authoring, as you can see below. &lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;While the bigger font size and strident red-on-yellow colors are ours the ‘highly highly’ is theirs :-)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/FkeQlSdKb-w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/FkeQlSdKb-w/visual-web-developer-team-ms-highly.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/visual-web-developer-team-ms-highly.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-5221153672923988854</guid><pubDate>Mon, 09 Mar 2009 14:45:00 +0000</pubDate><atom:updated>2009-03-09T07:47:56.478-07:00</atom:updated><title>Where did my Visual T4 IntelliSense go?</title><description>&lt;p&gt;   &lt;br /&gt;If you're using Refactor! or Resharper you will notice that the IntelliSense provided by the Visual T4 Editor for embedded C# code blocks doesn’t work as expected.&lt;/p&gt;  &lt;p&gt;The reason for this is the above mentioned tools replace the built-in Visual Studio C# IntelliSense and provide their custom ones.&lt;/p&gt;  &lt;p&gt;This doesn’t play well with any other tool expecting the built-in IntelliSense to be there, as it is the case for our Visual T4 Editor and the built-in ASP.NET editor which won’t also behave well if you have any of the two refactoring tools installed.&lt;/p&gt;  &lt;p&gt;The cure? Download and install &lt;a href="http://www.visualt4.com/VisualT4Editor-p20303.html" target="_blank"&gt;this patch&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Then: open Visual Studio and go to &lt;em&gt;Tools -&amp;gt; Options&lt;/em&gt;, open the tree at &lt;em&gt;Text Editor\T4 Editor\Miscellaneous &lt;/em&gt;and check the &lt;em&gt;Intellisense replacement&lt;/em&gt; item.&lt;/p&gt;  &lt;p&gt;This is a new experimental feature that tries to mitigate Refactor! and Resharper “hacky manners” of replacing the built-in IntelliSense and will get back to normal the IntelliSense support while editing a C# embedded code block in a T4 template.&lt;/p&gt;  &lt;p&gt;We’ve also detected that these refactoring tools don’t do a great job of restoring previous settings after uninstalling them, so it may be the case that you once used them but you currently don’t have any of them installed and you still don’t get proper IntelliSense. This can be fixed this way: go to &lt;em&gt;Tools –&amp;gt; Options&lt;/em&gt;, browse the tree at &lt;em&gt;Text Editor\C#\General &lt;/em&gt;and make sure &lt;em&gt;Auto list members&lt;/em&gt; is checked.&lt;/p&gt;  &lt;p&gt;We want to thank all of our customers that are also Refactor! or Reshaper customers and have reported this, you can all now enjoy the fix!.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/Tj2yyCYsuEs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/Tj2yyCYsuEs/where-did-my-visual-t4-intellisense-go.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/where-did-my-visual-t4-intellisense-go.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-3637535801661672340</guid><pubDate>Thu, 05 Mar 2009 07:41:00 +0000</pubDate><atom:updated>2009-03-09T07:19:17.155-07:00</atom:updated><title>Now supporting ASP.NET MVC code generation!</title><description>&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;/font&gt;: added correct download link&lt;/p&gt;  &lt;p&gt;After teasing you a bit &lt;a href="http://blog.visualt4.com/2009/02/customizing-generated-code-in-aspnet_04.html" target="_blank"&gt;here&lt;/a&gt; we took a couple of weeks to test this and have now added support for nice integration between the ASP.NET MVC bits and our &lt;a href="http://www.visualt4.com" target="_blank"&gt;Visual T4 Editor&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;If you are an existing customer who bought your copy before 03/03/09 you can download for free the patch to add support for this (and a few more other goodies) from &lt;a href="http://www.visualt4.com/VisualT4Editor-p20303.html" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;If you buy the &lt;a href="http://www.visualt4.com" target="_blank"&gt;Visual T4 Editor&lt;/a&gt; today, you will get this support right into the box, without having to install anything else.&lt;/p&gt;  &lt;p&gt;As you can see, we do care for keeping our &lt;a href="http://www.visualt4.com" target="_blank"&gt;Visual T4&lt;/a&gt; products updated up-to-the-minute to support all the new stuff that will be coming out from Microsoft and other companies regarding T4 adoption.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/EfgJHniEvSY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/EfgJHniEvSY/now-supporting-aspnet-mvc-code.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/now-supporting-aspnet-mvc-code.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-4867410728167701502</guid><pubDate>Mon, 02 Mar 2009 04:00:00 +0000</pubDate><atom:updated>2009-03-01T21:07:17.209-08:00</atom:updated><title>NHibernate configuration: Xml, Fluent or Attributes</title><description>When using NHibernate, you need to map tables to objects. Without this mapping, there is no way to reconcile the two models.  The mapping can be done in three very different ways: Attributes, Xml or Fluent syntax. Each model has its pros and cons. Let’s review them one by one. &lt;br/&gt;&lt;br/&gt; &lt;b&gt;&lt;font size="3"&gt;Fluent&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;  This is the newest way of doing OR/M in NHibernate. It works by providing a constructor that will establish the mappings using a Map() method, and by inheriting from a NHibernate provided class, like this:  &lt;pre class="brush: c-sharp;"&gt;public CustomerMap : ClassMap&amp;lt;Customer&amp;gt;  &lt;br /&gt;{  &lt;br /&gt;  public CustomerMap()  &lt;br /&gt;  {  &lt;br /&gt;    Id(x =&amp;gt; x.ID);  &lt;br /&gt;    Map(x =&amp;gt; x.FirstName);  &lt;br /&gt;    Map(x =&amp;gt; x.LastName);  &lt;br /&gt;    HasMany&amp;lt;Address&amp;gt;(x =&amp;gt; x.Addresses)  &lt;br /&gt;      .AsBag();  &lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can find more information about this type of mapping in &lt;a href="http://blog.jagregory.com" target="_blank"&gt;James Gregory’s blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Fluent mapping is cool, and it’s the newest way of mapping. This way of mapping is not officially supported, and it doesn’t cover every possible mapping, but it’s type safe (as it’s fluent), it’s really simple and it doesn’t use Xml. Also, since the mapping class is outside of the “Model” class, the model integrity is preserved.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font size="3"&gt;Attributes&lt;/font&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Attributes are also a very effective way of mapping without using Xml. When you use attributes, NHibernate creates the Xml for you on runtime. That is, you may not be using the xml config files, but the files are being generated and used anyway. Attributes are used like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;[NHibernate.Mapping.Attributes.Class]    &lt;br /&gt;public class Customer    &lt;br /&gt;{        &lt;br /&gt;    [NHibernate.Mapping.Attributes.Id(0, TypeType=typeof(int))]&lt;br /&gt;    public int ID;&lt;br /&gt;    [NHibernate.Mapping.Attributes.Property]        &lt;br /&gt;    public string FirstName;   &lt;br /&gt;    [NHibernate.Mapping.Attributes.Property] &lt;br /&gt;    public string LastName;   &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The cool thing about attributes is that you don’t violate the DRY principle. You do violate it (a lot) when using xml files. The bad thing about attributes is that they are all over your model. That pushes NHibernate all over the place instead of leaving it in your persistance layer (where it should be). Also, the attributes require a certain order, which is counterintuitive to the way attributes are generally used.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font size="3"&gt;Xml&lt;/font&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Xml is the standard format for configuration. It looks like this: &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;&amp;lt;hibernate-mapping xmlns=&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;&lt;br /&gt;    namespace=&amp;quot;MyNamespace&amp;quot; assembly=&amp;quot;MyAssembly&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;class name=&amp;quot;Customer&amp;quot; table=&amp;quot;Customers&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;id name=&amp;quot;ID&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;generator class=&amp;quot;identity&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;/id&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;FirstName&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;LastName&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;bag name=&amp;quot;Addresses&amp;quot; table=&amp;quot;Addresses&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;key column=&amp;quot;CustomerID&amp;quot;/&amp;gt;&lt;br /&gt;            &amp;lt;one-to-many class=&amp;quot;MyNamespace.Address, MyNamespace&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/bag&amp;gt;&lt;br /&gt;    &amp;lt;/class&amp;gt;&lt;br /&gt;&amp;lt;/hibernate-mapping&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This format is slightly more complex than the others, and it’s inherently not safe as it’s Xml and not code. It also forces you to repeat information already stated (class names, property names, etc). On the other hand, it’s completely transparent to your code, allowing you to take NHibernate out of the picture at any time, or adding it with no changes to your model.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font size="3"&gt;How this affects code generation&lt;/font&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If you’re generating your DAL using T4, your perspective on some of these issues may change a little. First, even though DRY is an important principle, it isn’t as important in code generation. You’re not repeating yourself, the generated code is. There’s a difference there: only one set to maintain (not two), and if the code is being regenerated in each build, then there’s nothing to maintain. That eliminates the main advantage of using attributes.&lt;br /&gt;&lt;br /&gt;Also, type safety isn’t that important because in generated code you’re not actually writing the code. Compile time safety is cool, but if your code is being properly generated you don’t have a big error-prone surface in the configuration. That eliminates the main advantage of using Fluent configuration.&lt;br /&gt;&lt;br /&gt;In code generated code, I always try to make the code as close as possible as code I would have written by hand. That is, no weird names, standard data types, regular patterns. Both Fluent (to a lesser extent) and Attributes provide a very strong binding to NHibernate. Also, Fluent is not (yet) fully functional and fully supported. Xml is still ugly, but it’s being generated automatically and it shouldn’t be modified by the developer.&lt;br /&gt;&lt;br /&gt;That’s why in the context of code generation I prefer to use Xml configuration instead of Attributes or Fluent.&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;&lt;em&gt;Written by Joaquin, joj AT clariusconsulting DOT net. Disclaimer: opinions expressed in this post are my own and not necessarily reflect those of Clarius Consulting.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/8pfZtmpxvmc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/8pfZtmpxvmc/nhibernate-configuration-xml-fluent-or.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>4</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/nhibernate-configuration-xml-fluent-or.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-3098070279689421847</guid><pubDate>Mon, 02 Mar 2009 01:17:00 +0000</pubDate><atom:updated>2009-03-01T17:17:53.532-08:00</atom:updated><title>Visual Studio 2010: we’re getting there.</title><description>&lt;p&gt;We’ve received a couple of emails now from (very) early adopters guys asking us if we do have a VS 2010 compatible version of our Visual T4 Editor and Visual T4 Code Generator.&lt;/p&gt;  &lt;p&gt;The answer is no, we don’t have one just yet.&lt;/p&gt;  &lt;p&gt;The reason is publicly available Visual Studio 2010 CTP bits are not ready yet to support the basics we need to make an early release of our tools.&lt;/p&gt;  &lt;p&gt;So, when can you expect our Visual T4 bits running on Visual Studio 2010? We’re working –a lot– on having some early bits that we will make available by when Visual Studio 2010 beta 1 goes out.&lt;/p&gt;  &lt;p&gt;And… when is Visual Studio 2010 beta 1 going out? Well, this is a question you should ask to Microsoft! :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/bR2NxLjLSsc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/bR2NxLjLSsc/visual-studio-2010-were-getting-there.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>2</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/03/visual-studio-2010-were-getting-there.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-3011245971812900419</guid><pubDate>Mon, 09 Feb 2009 23:14:00 +0000</pubDate><atom:updated>2009-02-09T15:16:21.388-08:00</atom:updated><title>Extending code generation with partial classes and inheritance</title><description>&lt;p&gt;One of the bigger problems with Code Generation is changeability. Generated code should never be modified. Anything that you modify on a generated class will be lost when you run the generation again. The problem is that if you need to extend/alter your generated class, you cannot do it without taking it out of the generation process (which is sometimes acceptable, but mostly not).&lt;/p&gt;  &lt;p&gt;Gladly, C# 2.0 introduced the concept of “partial” classes a long time ago. You must have seen it. When you create a new Windows Form, you get two classes; one is for the generated code in InitializeComponents and the other is for you to use. If your architecture is similar to this case, you can do the same: generate a partial class with all the generated code and have a partial class with any extra code the developer may need to add.&lt;/p&gt;  &lt;p&gt;Most of the times, though, the need is to replace the generated code with something completely different in some specific cases. That is, almost all the generated code is ok, but one or two methods in one or two classes need to be replaced. In this case, you can use a different approach: the “double-derived” pattern introduced in Microsoft DSL. It works like this:&lt;/p&gt;  &lt;p&gt;When you generate code, you generate 2 classes instead of one. The first class (MyGeneratedClassBase) will have all the methods implemented and marked as virtual. The second class (MyGeneratedClass) will inherit from the first class, and will be marked as partial. This will be transparent to whoever needs to use the class and it will allow you to change the implementation of the methods you need via overriding. If you regenerate the classes afterwards, nothing breaks.&lt;/p&gt;  &lt;p&gt;Let me show you in an example. Say you are generating classes from a database. You generate each table with properties for the fields and CRUD methods. Something like this:&lt;/p&gt;  &lt;pre class="brush: c-sharp;"&gt;public class Customer&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    public int Id { get; set; }&lt;br /&gt;    public string FirstName { get; set; }&lt;br /&gt;    public string LastName { get; set; }&lt;br /&gt;&lt;br /&gt;    public int Create() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Update() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Delete() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Retrieve() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, let’s suppose you need to override the Delete method so you will not be allowed to delete customers (let’s assume this makes sense just for the sample). If you change the generated class directly, you’ll loose your changes when the class is regenerated. In the double-derived pattern, you’ll have this instead:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;public class CustomerBase&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    public virtual int Id { get; set; }&lt;br /&gt;    public virtual string FirstName { get; set; }&lt;br /&gt;    public virtual string LastName { get; set; }&lt;br /&gt;&lt;br /&gt;    public virtual int Create() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public virtual void Update() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public virtual void Delete() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public virtual void Retrieve() &lt;br /&gt;    {&lt;br /&gt;        //some implementation&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public partial class Customer : CustomerBase&lt;br /&gt;{&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A developer will use the Customer class as before, but now you can create a new partial class for Customer, overriding the Delete method like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;public partial class Customer&lt;br /&gt;{&lt;br /&gt;    public override void Delete()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Notice that this class is not the same as the generated class, but a new partial class created by you. Also notice that you cannot change the return value for the method. You can change the parameters of the method by creating a new overload for it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This way you’ll be able to change standard implementation on a need-to-change basis while still using your code generation for most of your code. Also, you can regenerate on every build if needed. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/A_tys5tpf1Y" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/A_tys5tpf1Y/extending-code-generation-with-partial.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/02/extending-code-generation-with-partial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-2625703896599370419</guid><pubDate>Mon, 09 Feb 2009 17:17:00 +0000</pubDate><atom:updated>2009-02-09T09:18:49.203-08:00</atom:updated><title>Registry-based configuration</title><description>&lt;p&gt;When you need to design your system’s configuration options, one of the available options is to use the Windows Registry. The Registry has several advantages and disadvantages over an xml-based .config file. Let’s go through them:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Pros      &lt;ul&gt;       &lt;li&gt;Windows Standard &lt;/li&gt;        &lt;li&gt;Strongly-typed data &lt;/li&gt;        &lt;li&gt;User Configuration &lt;/li&gt;        &lt;li&gt;Atomicity &lt;/li&gt;        &lt;li&gt;Remote Administration &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Cons      &lt;ul&gt;       &lt;li&gt;Difficult to manipulate / Bad tools &lt;/li&gt;        &lt;li&gt;Difficult to backup &lt;/li&gt;        &lt;li&gt;May leave unused data behind &lt;/li&gt;        &lt;li&gt;Can’t easily move settings to a different computer &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;All of this makes registry-based configuration a good choice for two types of configuration: advanced settings (of the type that no normal user should be touching, but an advanced user may need to change) and user settings (such as last position of a window on the screen, last search parameters, etc). &lt;/p&gt;  &lt;p&gt;The focus is to do this:&lt;/p&gt;  &lt;pre class="brush: c-sharp;"&gt;configuration.WindowsPosition.Top = top;&lt;br /&gt;configuration.WindowsPosition.Left = left;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;instead of this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;windowPositionKey = Registry.CurrentUser.OpenSubKey(@&amp;quot;Software\MyCompany\MyProgram\1.0\WindowsPosition&amp;quot;, true);&lt;br /&gt;windowPositionKey.SetValue(&amp;quot;Top&amp;quot;, top);&lt;br /&gt;windowPositionKey.SetValue(&amp;quot;Left&amp;quot;, left);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;When using the registry for configuration, it makes code more explicit and simpler, which is always a plus.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;So, how does this work? First, the generated class will look like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;public class WindowPositionKey&lt;br /&gt;{&lt;br /&gt;    private Microsoft.Win32.RegistryKey registry;&lt;br /&gt;    &lt;br /&gt;    public override string KeyName&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            return @&amp;quot;WindowPosition&amp;quot;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public WindowPositionKey()&lt;br /&gt;    {&lt;br /&gt;        registry = Registry.LocalMachine.OpenSubKey@&amp;quot;Software\MyCompany\MySoftware\1.0\Configuration\WindowPosition&amp;quot;, true);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int Top&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            return (int) registry.GetValue(@&amp;quot;Top&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            registry.SetValue(@&amp;quot;Top&amp;quot;, value);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int Left&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            return (int) registry.GetValue(@&amp;quot;Left&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            registry.SetValue(@&amp;quot;Left&amp;quot;, value);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;It looks pretty simple, and it can even be made manually. And that is generally true for any code generation task. The point here is quantity. When you have several configuration values in different keys, it makes sense to have a tool generate all that code for you. Also, you can do some fancy stuff. For instance, the key named “Configuration” may have several subkeys (let’s say, WindowPosition and ConnectionProxy for this sample). That code will look like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;public class RootRegistryKey : RegistryGen.RegistryKey&lt;br /&gt;{&lt;br /&gt;    private Microsoft.Win32.RegistryKey registry;&lt;br /&gt;        &lt;br /&gt;    public override string KeyName&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            return @&amp;quot;Configuration&amp;quot;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;        &lt;br /&gt;    public RootRegistryKey()&lt;br /&gt;    {&lt;br /&gt;        registry = Registry.LocalMachine.OpenSubKey(@&amp;quot;Software\MyCompany\MySoftware\1.0\Configuration&amp;quot;, true);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public WindowPositionKey WindowPosition&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            return new WindowPosition(registry);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public ConnectionProxyKey ConnectionProxy&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            return new ConnectionProxyKey(registry);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override IList&amp;lt;RegistryGen.RegistryKey&amp;gt; GetSubKeys()&lt;br /&gt;    {&lt;br /&gt;        IList&amp;lt;RegistryGen.RegistryKey&amp;gt; keys = new List&amp;lt;RegistryGen.RegistryKey&amp;gt;();&lt;br /&gt;&lt;br /&gt;        keys.Add(WindowPosition);&lt;br /&gt;        keys.Add(ConnectionProxy);&lt;br /&gt;        return keys;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There are a few changes in WindowPositionKey that must be implemented for this to work. First, we need a constructor with a Microsoft.Win32.RegistryKey parameter. Also, it should inherit from RegistryGen.RegistryKey for the GetSubKeys() method. As you add levels of complexity, manually coding the classes gets more complex. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The code generation task, though, is almost exactly the same. We have a GenerateClass() method that receives all the necessary information to generate a single registry class (className, fullName, etc). For the first change, you only need to change this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;public class &amp;lt;#= CleanName(className) #&amp;gt;Key&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;to this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;public class &amp;lt;#= CleanName(className) #&amp;gt;Key : &amp;lt;#= Namespace #&amp;gt;.RegistryKey&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The second change is as easy. Just change this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;public &amp;lt;#= CleanName(className) #&amp;gt;Key()&lt;br /&gt;{&lt;br /&gt;    registry = Registry.&amp;lt;#= GetRootString(registryParts) #&amp;gt;.OpenSubKey(@&amp;quot;&amp;lt;#= fullName #&amp;gt;&amp;quot;, true);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;to this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;internal &amp;lt;#= CleanName(className) #&amp;gt;Key(Microsoft.Win32.RegistryKey registry)&lt;br /&gt;{&lt;br /&gt;    this.registry = registry.OpenSubKey(@&amp;quot;&amp;lt;#= lastPart #&amp;gt;&amp;quot;, true);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;and you’re all set!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;If you’re interested, you can review the RegistryGen sample in Visual T4 Code Generator alpha for the full sample. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/tVcoDuFuqGY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/tVcoDuFuqGY/registry-based-configuration.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/02/registry-based-configuration.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-5617226134040558298</guid><pubDate>Mon, 09 Feb 2009 01:14:00 +0000</pubDate><atom:updated>2009-02-08T19:20:21.180-08:00</atom:updated><title>Creating valid C# identifiers</title><description>&lt;p&gt;In code generation, it’s very common to need to create a valid identifier. For instance, you may need to create a class name, field, property, method, etc based on the name of a table, a file name, a registry key. The problem with this type of generation is that the rules that make one valid may not apply to the other. For instance, “1st File.txt” is a perfectly valid file name, but it’s not a valid C# identifiers. &lt;/p&gt;&lt;p&gt;Valid identifiers in C# are defined in the &lt;a href="http://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx" target="_blank"&gt;C# Language Specification, item 2.4.2&lt;/a&gt;. The rules are very simple: &lt;/p&gt;&lt;p&gt;- An identifier must start with a letter or an underscore&lt;br /&gt;- After the first character, it may contain numbers, letters, connectors, etc&lt;br /&gt;- If the identifier is a keyword, it must be prepended with “@” &lt;/p&gt;&lt;p&gt;Applying these rules is pretty straightforward. The following code validates items 1 and 2: &lt;/p&gt;&lt;pre class="brush: c-sharp;"&gt;private string CleanName(string name)&lt;br /&gt;&lt;br /&gt;{ //Compliant with item 2.4.2 of the C# specification&lt;br /&gt;System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]");&lt;br /&gt;string ret = regex.Replace(name, "_"); //The identifier must start with a character if (!char.IsLetter(ret, 0))&lt;br /&gt;&lt;br /&gt;ret = string.Concat("_", ret);&lt;br /&gt;return ret;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To validate item 3, you can use the C# provider as follows: &lt;/p&gt;&lt;pre class="brush: c-sharp;"&gt;ret = Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#").CreateEscapedIdentifier(ret); &lt;/pre&gt;&lt;p&gt;&lt;br /&gt;This code will generate an underscore for each space in the identifier. For instance, “c:\1st file.txt” will be generated as “c__1st_file_txt”. If you want to prevent that, change the regex.Replace(name, “_”) with regex.Replace(name, “”). You may also consider capitalizing the first letter after each “_” and then eliminating the “_”. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Finally, you may prefer to have the “keyword” identifiers named with a prefix different from “@”. If that’s the case, use IsValidIdentifier in the CodeDomProvider to know which identifiers are keywords. A full corrected code snippet is below: &lt;/p&gt;&lt;pre class="brush: c-sharp;"&gt;private static string CleanName(string name)&lt;br /&gt;{&lt;br /&gt;//Compliant with item 2.4.2 of the C# specification&lt;br /&gt;&lt;br /&gt;System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]");&lt;br /&gt;string ret = regex.Replace(name, "");&lt;br /&gt;//The identifier must start with a character or a "_"&lt;br /&gt;if (!char.IsLetter(ret, 0)  !Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#").IsValidIdentifier(ret))&lt;br /&gt;  &lt;br /&gt;ret = string.Concat("_", ret);&lt;br /&gt;return ret;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The only problem you may find after this is with duplicated identifiers. “c:x” will generate the same identifier as “c.x”, which may be a problem depending on your particular code generation needs. If you run into this, use a list to store already used identifiers. When you find that an identifier has been used, add a number at the end and check again.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/S5K5XQC020Y" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/S5K5XQC020Y/creating-valid-c-identifiers.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>9</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/02/creating-valid-c-identifiers.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-4679442721691466672</guid><pubDate>Wed, 04 Feb 2009 15:15:00 +0000</pubDate><atom:updated>2009-02-04T07:15:00.937-08:00</atom:updated><title>Customizing generated code in ASP.NET MVC</title><description>&lt;p&gt;Just in case you missed &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/12/19/asp-net-mvc-design-gallery-and-upcoming-view-improvements-with-the-asp-net-mvc-release-candidate.aspx" target="_blank"&gt;the&lt;/a&gt;&amp;#160;&lt;a href="http://haacked.com/archive/2009/01/31/t4-templates-in-asp.net-mvc.aspx" target="_blank"&gt;news&lt;/a&gt;, the ASP.NET MVC team is using T4 to generate code (yeah!)     &lt;br /&gt;The way they have integrated T4 in their own product is not what we would have expected (they wrote their own T4 host) so we took our Visual T4 Editor and Visual T4 Code Generator bits and added them knowledge about this custom host in order to offer the best possible tooling experience.&lt;/p&gt;  &lt;p&gt;You can now see properties of their templates appearing in the Properties window, easily set them and preview how the generation will look like with a single click.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://adrianalonso.blogspot.com/" target="_blank"&gt;Adrian&lt;/a&gt; has recorded a quick video of how this is looking like already, watch it &lt;a href="http://www.visualt4.com/aspnetmvc-rc.htm" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We added this support last week so it is not there yet on the public bits, but I promess it will be there soon!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/CiRQ8hO98SE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/CiRQ8hO98SE/customizing-generated-code-in-aspnet_04.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/02/customizing-generated-code-in-aspnet_04.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4244396226795190974.post-8927085463633513150</guid><pubDate>Tue, 03 Feb 2009 22:36:00 +0000</pubDate><atom:updated>2009-02-03T22:26:10.496-08:00</atom:updated><title>New Blog About Code Generation With T4 in Visual Studio!</title><description>&lt;p&gt;While developing the &lt;a href="http://www.visualt4.com/" target="_blank"&gt;Visual T4 Code Generator&lt;/a&gt; edition my team and I are constantly having discussions on how the best code generation tool in earth should look like and also about more “abstract” code generation chores not necessarily related to the product we’re developing.&lt;/p&gt;&lt;p&gt;So it occurred to me (yes, I’m that clever…) that we should take our internal document drafts from our internal wiki and put all this stuff into a blog (of course we will remove the bad language first) to make our plans more public and gather community feedback while we’re at it.&lt;/p&gt;&lt;p&gt;In this &lt;a href="http://blog.visualt4.com/" target="_blank"&gt;new blog&lt;/a&gt; you will find posts by &lt;a href="http://adrianalonso.blogspot.com/" target="_blank"&gt;Adrian&lt;/a&gt;, &lt;a href="http://geekswithblogs.net/osnosblog/Default.aspx" target="_blank"&gt;Joaquin&lt;/a&gt;, &lt;a href="http://weblogs.asp.net/jescrich/default.aspx" target="_blank"&gt;Jose&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/vga" target="_blank"&gt;me&lt;/a&gt; (and if I get lucky I may get other &lt;a href="http://www.clariusconsulting.net/" target="_blank"&gt;Clarius&lt;/a&gt; people to blog too)&lt;/p&gt;&lt;p&gt;Please &lt;a href="http://feeds.feedburner.com/VisualT4Blog" target="_blank"&gt;subscribe&lt;/a&gt; and let us know what do you think, thanks!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VisualT4Blog/~4/UU5zxehn09s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/VisualT4Blog/~3/UU5zxehn09s/new-blog-about-code-generation-with-t4.html</link><author>noreply@blogger.com (Visual T4)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.visualt4.com/2009/02/new-blog-about-code-generation-with-t4.html</feedburner:origLink></item></channel></rss>
