Understanding the code-behind model

A CodeSmith Generator template contains two kinds of code:

  1. The code being generated.
  2. The template code that controls the generation.

To Generator, the generated code is just text, so it can be in any language at all: VB, SQL, Fortran, COBOL, anything that can be represented as a string of characters.

The template code is more restricted: it must be C#, Visual Basic or JScript. But you have a choice of where to keep it. You can put it in the template itself, in <script runat="template"> blocks, or in a separate code-behind file: a source file that contains only template code and is attached to the template through attributes of the CodeTemplate directive.

Example

This template uses a code-behind file:

<%@ CodeTemplate Src="VBCodeBehind.cst.vb" Inherits="UtilityCodeTemplate" Language="VB" TargetLanguage="VB" %>
<%@ Property Name="ClassName" Type="System.String" Category="Options" Description="The name of the generated class." %>
' This class generated by CodeSmith on <%= DateTime.Now.ToLongDateString() %>
<%= GetAccessModifier(Accessibility) %> Class <%= ClassName %>

    Public Sub New()
    End Sub

        ' Write your class here

End Class

The template uses a GetAccessModifier function and an Accessibility property, but defines neither of them. They come from the code-behind file, VBCodeBehind.cst.vb:

Imports System.ComponentModel
Imports CodeSmith.Engine

' This class contains utility functions that can be
' used across many templates

Public Class UtilityCodeTemplate
    Inherits CodeTemplate

    Private _Accessibility As AccessibilityEnum = AccessibilityEnum.Public

    <Category("Options"), _
    Description("Accessibility of the generated class")> _
    Public Property Accessibility As AccessibilityEnum
        Get
            Return _Accessibility
        End Get
        Set
            _Accessibility = value
        End Set
    End Property

    Public Enum AccessibilityEnum
        [Public]
        [Protected]
        [Friend]
        [ProtectedFriend]
        [Private]
    End Enum

    Public Function GetAccessModifier(ByVal accessibility As AccessibilityEnum) As String
        Select accessibility
            Case AccessibilityEnum.Public
                GetAccessModifier = "Public"
            Case AccessibilityEnum.Protected
                GetAccessModifier = "Protected"
            Case AccessibilityEnum.Friend
                GetAccessModifier = "Friend"
            Case AccessibilityEnum.ProtectedFriend
                GetAccessModifier = "Protected Friend"
            Case AccessibilityEnum.Private
                GetAccessModifier = "Private"
            Case Else
                GetAccessModifier = "Public"
        End Select
    End Function
End Class

The CodeTemplate directive ties the two together:

  • Src names the code-behind file.
  • Inherits names the class in that file that the template is based on. This class must inherit, directly or indirectly, from CodeSmith.Engine.CodeTemplate.

Because Accessibility is a property of the UtilityCodeTemplate class, Generator shows it in the template's property grid:

Property grid for VBCodeBehind.cst with the Accessibility drop-down open, listing Public, Protected, Friend, ProtectedFriend and Private

Why use a code-behind file

  • Readability. It separates the generated code from the code that drives the generation.
  • Reuse. Utility functions in a shared code-behind file can be used by many templates.

To compile a code-behind file as a partial class of the template, also set the ClassName and Namespace attributes of the CodeTemplate directive. For other ways to share code, see Sharing common code.