.NET
  Home arrow .NET arrow Page 5 - Introducing Code Generation
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Moblin 
JMSL Numerical Library 
Windows Web Hosting
 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
.NET

Introducing Code Generation
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 9
    2004-12-08

    Table of Contents:
  • Introducing Code Generation
  • Generating a Simple Program
  • Creating the Template
  • Running the Template
  • Plain-Vanilla Code
  • Picking the Right Mechanism
  • Breaking Down the Code Generation Process
  • Writing Handcrafted Code
  • Tying It Together: Implementation and Testing
  • The Strongly Typed Dataset
  • Performing Real-World Code Generation
  • Generating a Simple Class via CodeDOM
  • Generating a Simple Class via XSLT Templates

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Introducing Code Generation - Plain-Vanilla Code


    (Page 5 of 13 )

    Another fundamental issue plagues the CodeDOM. For the CodeDOM to create code valid in all languages, the abstraction can only work with elements found in all languages. You’re forced to write code from a least common denominator approach, using only elements that appear in all languages. For example, you can’t use VB .NET’s project-level namespaces or WithEvents, With, or Event. You have to understand subtle but important differences in constructs such as between VB .NET’s Imports and C#’s using. There’s no built-in support for preprocessor directives, including region directives. The CodeDOM doesn’t even support all features currently provided by both languages (see Chapter 3 for details). Also, it isn’t clear how frequently the CodeDOM will be updated with new language features as .NET evolves because the CodeDOM wasn’t updated to reflect new language features between .NET 1.0 and 1.1 (Visual Studio 2002 and 2003).

    And to make this worse, I know of no reference you can rely on to list all of the caveats and special considerations (except the ones I discuss in Chapter 3 and Appendix D). The result is that not only do you have to write plain-vanilla code, but you have to think that way. This effort is only justified if your job is specifically to create code in multiple languages and you can afford to ignore some of the best features in each language.

    Generating “Hello World” via XSLT Templates

    The third approach is relatively novel in .NET. This is code generation using XSLT templates. XSLT is a template language designed to create any type of text, XML, or Hypertext Markup Language (HTML) output from XML input. Because source code is text output, XSLT can create source code.

    The XSLT language might be new to you, and it might appear to be a strange paradigm. It presents a new way of thinking because it’s explicitly designed from the ground up to apply patterns to information in order to transform information into text. Because metadata is information and source code is text, XSLT does exactly the job presented by code generation.

    ***********

    TIP Appendix A introduces XML, XPath, XML Schema Definition (XSD), and XSLT technologies targeted to what you need for code generation.

    Understanding the Benefits of XSLT Code Generation

    XSLT code generation presents a couple of compelling benefits. First, the template is closer in appearance to your output code. You can create a functioning sample class, copy code from the sample class into the XSLT template shell, and add tags to indicate the variable content that depends on metadata information. The templates are far more readable, editable, and easily searchable for .NET elements. It’s much easier to segment processing to isolate complex sequences and mimic the resulting document sufficiently to support continued maintenance of templates.

    When you’re working with code templates, searches can be problematic, especially if you’re using CodeDOM or brute force because you’re overlaying the syntax of the output code with the code that runs the template. For example, regions are your primary tool in correlating output with the part of the template that produces it. If you search for the word region, your results will include the regions that are part of the generating code itself, as well as those destined for your target output. String concatenations further complicate your searches, especially when your target contains quotes. XSLT avoids these problems almost entirely because the syntax of XSLT differs markedly from the syntax you’re outputting. XSLT is also flexible about the use of single and double quotes, allowing easier handling of nested strings.

    An important secondary benefit is that XSLT code generation doesn’t allow you to cheat on the isolation of metadata. Later in this chapter and in Chapter 2, you’ll see the benefits of isolating metadata and its creation. In a brute-force or CodeDOM approach, you could mix running queries that grab fragments of information into the code outputting process. Mixing these two processes makes debugging and reuse difficult. XSLT forces this separation of metadata collection and code generation. You can also supply this separation manually with brute-force or CodeDOM generation.

    In Chapter 3 you’ll see generating code as a process that contains many steps, and you’ll see how to orchestrate these steps via a script. I call the tool that runs this script the code generation harness, or just the harness. When you’re working with the code generation harness, you can edit XSLT and regenerate without stopping and restarting the harness. Because brute-force and CodeDOM templates are compiled .NET code, the modules containing them are loaded in the harness’s process space. These modules aren’t unloaded, so you have to stop the harness before you compile changes to the templates. Because no method of code generation avoids syntax errors, you’ll be generating code, finding syntax errors, correcting your code templates, and rerunning the generation. The turnaround for fixing common silly mistakes will be significantly faster with XSLT because you don’t need to stop and restart the code generating application.

    The core of XSLT is XPath, which you have to learn anyway. XPath is the language used to query XML within .NET (and most other technologies). Even if you’re doing code generation through one of the other techniques, you’ll be learning and using XPath if you’re using XML metadata.

    Running the Template

    To create the output, the example calls a generic GenerateViaXSLT method, passing the name of the template:

    ' Generate Hello World via XSLT Template GenerateViaXSLT(IO.Path.Combine(xsltDir, "HelloWorld.xslt"), Nothing, _ IO.Path.Combine(outputDir, "HelloWorldViaXSLT.vb"))

    *************

    TIP Shared methods of the IO.Path class allow you to do various cool things with file paths. In this case, IO.Path.Combine combines paths, letting you ignore whether intervening backslashes are handled correctly and other details.

    GenerateViaXSLT wraps the powerful XSLT features of the System.Xml.Xsl namespace. This method takes the name of the XSLT file, an XML document to transform, and the name of the output file. The method that provides the outputting is generic because the entire template is contained in the XSLT file. You can pass parameters, but the “Hello World” program requires neither an input XML file nor parameters:

    Private Shared Sub GenerateViaXSLT( _

    ByVal xsltFileName As String, _

    ByVal xmlMetaData As Xml.XmlDocument, _

    ByVal outputFile As String, _

    ByVal ParamArray params() As xsltparam)

    Objects created from several XML and XSLT classes handle the translation. The XslTransform object performs the actual translation. XSLT works most efficiently if the input XML is an XPathNavigator because XPathNavigator objects have internal features for efficient XPath access. The StreamWriter takes the output of the transformation:

    Dim xslt As New Xml.Xsl.XslTransform Dim xNav As Xml.XPath.XPathNavigator Dim streamWriter As IO.StreamWriter

    This method creates an XML document if you don’t pass one because the transformation needs at least an empty XML document for input. It also creates XSLT parameters if you pass any parameter values:

    Dim args As New Xml.Xsl.XsltArgumentList Dim param As XSLTParam

    Try If xmlMetaData Is Nothing Then xmlMetaData = New Xml.XmlDocument End If

    For Each param In params args.AddParam(param.Name, "", param.Value) Next

    The method then creates the navigator from the XML document and creates the StreamWriter connected to the output file:

    xNav = xmlMetaData.CreateNavigator() streamWriter = New IO.StreamWriter(outputFile)

    Once everything is ready, the method just loads the XSLT file and performs the transform. When the call to the Transform3 method is complete, the code is output although you won’t see it if you forget to flush the stream:

    xslt.Load(xsltFileName) xslt.Transform(xNav, args, streamWriter, Nothing)

    As with other approaches, flush and close before you leave the method. Placing this in the Finally block ensures it can’t be bypassed:

    Finally

    If Not streamWriter Is Nothing Then streamWriter.Flush() streamWriter.Close()

    End If End Try

    End Sub

    Creating the Template

    XSLT templates intersperse the .NET output code with XSLT directives. Not only is this more readable, but I created it by copying the target code into the stylesheet. Because I had already modified my default template so it contained the header I use, creating this template took less than 60 seconds.

    ***********

    3. The Transform method underwent considerable revision between .NET 1.0 and .NET 1.1. The changes mostly involved supporting XML resolvers. You probably won’t need to be concerned with resolvers when doing code generation and can pass Nothing for the resolver.

    ******************

    TIP See Appendix A for information about how you modify your default XSLT template to provide the starting point you want.

    Each XSLT stylesheet starts with some standard XSLT “goo,” including a legal XML header. Although it isn’t strictly required, XSLT is a specialized version of XML, so it’s a good idea to include a legal XML header. XML requires a single root element, and for XSLT stylesheets this is the xsl:stylesheet4 element. This element contains attributes defining the namespaces for the transformation. Appendix A discusses namespaces and the rest of the file opening goo in detail as well as shows you how to automate the header creation via your default template so you can fix it once and forget about it:

    <?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8" indent="yes"/> <xsl:preserve-space elements="*" />

    Stylesheets contain templates, and templates do the real work of XSLT code generation. I copied the sample code into the single template in this stylesheet. XSLT will output verbatim any text that appears in a template that isn’t an XSLT directive:

    <xsl:template match="/"> Option Strict On Option Explicit On

    Imports System

    ' Class Summary:

    Public Class TargetOutput

    #Region "Public Methods and Properties" Public Shared Sub Main() Console.WriteLine("Hello World") End Sub #End Region

    End Class </xsl:template> </xsl:stylesheet>

    ***************

    4. xsl:transform is synonymous with xsl:stylesheet, and you can use either as the stylesheet root. I standardize on xsl:stylesheet.

    Because XSLT is well-formed XML, template and stylesheet closing tags appear at the end of the file. That’s it. That’s all there is to XSLT code generation. (Okay, there’s really more to it when you’re generating real-world code with tokens and internal logic, but that’s a start at seeing how you can copy code into your templates.)  

    This chapter is from Code Generation in Microsoft .NET by Kathleen Dollard (Apress, 2004, ISBN: 1590591372). Check it out at your favorite bookstore today.

    Buy this book now.

    More .NET Articles
    More By Apress Publishing


     

    .NET ARTICLES

    - Using CrystalReportViewer to Display Crystal...
    - Creating Summary .Net Crystal Reports
    - More on Commands, Input and the WPF
    - Grouping and Aggregating When Querying LINQ ...
    - Commands, Input and the WPF
    - Keyboard and Ink Input with WPF
    - Mouse Input and the WPF
    - Input with Windows Presentation Foundation
    - Introducing LINQ with XML and Databases
    - An Introduction to LINQ
    - Querying LINQ to SQL: Basics
    - Completing a Simple Storefront with LINQ
    - Knowing Your Environment: the System.Environ...
    - Creating the Home Page for a Simple Storefro...
    - LINQ Quickly with Language Integrated Queries





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway
    Stay green...Green IT