3. Adapdev.CodeGen

The Adapdev.CodeGen namespace is provided to assist with code generation. It wraps generation capabilities for CodeDOM and for NVelocity, an excellent templating language.

3.1. Generating with CodeDOM

CodeDOM is an API, provided by the Microsoft .NET Framework, that allows you to build code using one code base but generate to multiple languages. Adapdev.CodeGen.CodeGenerator wraps the CodeDOM functionality and simplifies its usage. It also supplies all of the required assemblies for C++ and JSharp generation, which normally require VS.NET.

The CodeGenerator class expects an ICodeDomTemplate. This interface defines several options, to include the output file name, whether the generated file should overwrite previous versions, etc.

To use CodeGenerator, just initialize it and then pass in the ICodeDomTemplate to generate from.

3.1.1. Generating to Memory

In the example below, we create a simple class called CodeDOMSample, which implements ICodeDomTemplate. The most important piece is the method implementation for GetCodeCompileUnit, since it defines the CodeDOM to be generated.

Basic ICodeDomTemplate Implementation

using System;
using System.CodeDom;
using System.Reflection;

namespace Adapdev.CodeGen.Tests
{
	/// <summary>
	/// Summary description for CodeDOMSample.
	/// </summary>
	public class CodeDOMSample : ICodeDomTemplate
	{
		public CodeDOMSample()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		#region ICodeDomTemplate Members

		public void ProcessCustomCode()
		{
			// TODO:  Add CodeDOMSample.ProcessCustomCode implementation
		}

		public bool Overwrite
		{
			get
			{
				// TODO:  Add CodeDOMSample.Overwrite getter implementation
				return false;
			}
			set
			{
				// TODO:  Add CodeDOMSample.Overwrite setter implementation
			}
		}

		public CodeCompileUnit GetCodeCompileUnit()
		{
			CodeCompileUnit compileUnit = new CodeCompileUnit();
			CodeNamespace namespace1 = new CodeNamespace("TestNamespace");
			compileUnit.Namespaces.Add( namespace1 );
			return compileUnit;
		}

		public string Namespace
		{
			get
			{
				// TODO:  Add CodeDOMSample.Namespace getter implementation
				return "Adapdev.CodeGen";
			}
			set
			{
				// TODO:  Add CodeDOMSample.Namespace setter implementation
			}
		}

		public string FileName
		{
			get
			{
				// TODO:  Add CodeDOMSample.FileName getter implementation
				return "CodeDOMSample";
			}
			set
			{
				// TODO:  Add CodeDOMSample.FileName setter implementation
			}
		}

		public string OutputDirectory
		{
			get
			{
				// TODO:  Add CodeDOMSample.OutputDirectory getter implementation
				return "output";
			}
			set
			{
				// TODO:  Add CodeDOMSample.OutputDirectory setter implementation
			}
		}

		public string ClassName
		{
			get
			{
				// TODO:  Add CodeDOMSample.ClassName getter implementation
				return "CodeDOMSample";
			}
			set
			{
				// TODO:  Add CodeDOMSample.ClassName setter implementation
			}
		}

		#endregion
	}
}

Generation with CodeGenerator

CodeGenerator c = new CodeGenerator(AppDomain.CurrentDomain.BaseDirectory);
string output = c.ProcessICodeDomTemplate(new CodeDOMSample(), LanguageType.VBNET);

// Output:
'------------------------------------------------------------------------------
' <autogenerated>
'     This code was generated by a tool.
'     Runtime Version: 1.1.4322.2032
'
'     Changes to this file may cause incorrect behavior and will be lost if 
'     the code is regenerated.
' </autogenerated>
'------------------------------------------------------------------------------

Option Strict Off
Option Explicit On


Namespace TestNamespace
End Namespace

To change the output language type, just specify a different LanguageType parameter.

3.1.2. Generating To a File

You can also generate to a physical file vs in-memory. The below example will create a file, specified by the FileName property, in the specified OutputDirectory. It automatically appends the correct file extension. Since CodeDOMSample specifies the FileName of CodeDOMSample, the example below would generate CodeDOMSample.java. If LanguageType.CSHARP were specified, the generated file would be CodeDOMSample.cs:

CodeGenerator c = new CodeGenerator(AppDomain.CurrentDomain.BaseDirectory);
string output = c.ProcessICodeDomTemplateToFile(new CodeDOMSample(), LanguageType.JSHARP);

3.2. Generating with NVelocity

NVelocity is a very powerful template language, ported from the original Java-based Velocity language. Adapdev.CodeGen contains a slightly modified version of the original NVelocity distribution. Since the last NVelocity release was late 2003, the Adapdev version has several bug fixes and minor improvements.

To understand how to use the Velocity template language, please visit the Velocity website for a full set of examples.

Important

In order to process NVelocity templates, you must have the directive.properties and nvelocity.properties files in your executable directory. These files are included with the Adapdev distribution.

3.2.1. Generating to Memory

You can load a NVelocity template and generate the results to memory. To do so, just add any context assignments. The below example contains a very simple template file.

template.t

Today's date is $date

Generation from a File

NVelocityTemplate template = new NVelocityTemplate();
template.AddContext("date",DateTime.Now);
template.SetFileTemplate("template.t");
string text = template.GetOutput();
Console.WriteLine(text);

// Output:
Today's date is 4/18/2006 9:07:24 PM

Generation from Memory

You can also define the template itself dynamically, in-memory. This example defines the same template, but doesn't use a file to do so:

NVelocityTemplate template = new NVelocityTemplate();
template.AddContext("date",DateTime.Now);
template.SetTemplate("Today's date is $date");
string text = template.GetOutput();
Console.WriteLine(text);

// Output:
Today's date is 4/18/2006 9:07:24 PM