Using the CodeDOM

The CodeDOM provides types that represent many common types of source code elements. You can design a program that builds a source code model using CodeDOM elements to assemble an object graph. This object graph can be rendered as source code using a CodeDOM code generator for a supported programming language. The CodeDOM can also be used to compile source code into a binary assembly.

Some common uses for the CodeDOM include:

  • Templated code generation: generating code for ASP.NET, XML Web services client proxies, code wizards, designers, or other code-emitting mechanisms.
  • Dynamic compilation: supporting code compilation in single or multiple languages.

Building a CodeDOM Graph

The System.CodeDom namespace provides classes for representing the logical structure of source code, independent of language syntax.

The Structure of a CodeDOM Graph

The structure of a CodeDOM graph is like a tree of containers. The top-most, or root, container of each compilable CodeDOM graph is a CodeCompileUnit. Every element of your source code model must be linked into the graph through a property of a CodeObject in the graph.

Building a Source Code Model for a Sample Hello World Program

The following walkthrough provides an example of how to build a CodeDOM object graph that represents the code for a simple Hello World application. For the complete source code for this code example, see the System.CodeDom.Compiler.CodeDomProvider topic.

Creating a compile unit

The CodeDOM defines an object called a CodeCompileUnit, which can reference a CodeDOM object graph that models the source code to compile. A CodeCompileUnit has properties for storing references to attributes, namespaces, and assemblies.

The CodeDOM ICodeGenerator and ICodeCompiler interfaces contain methods that process the object graph referenced by a CodeCompileUnit.

To create an object graph for a simple application, you must assemble the source code model and reference it from a CodeCompileUnit.

You can create a new compile unit with the syntax demonstrated in this example:

Dim compileUnit As New CodeCompileUnit()
[C#]
CodeCompileUnit compileUnit = new CodeCompileUnit();

A CodeSnippetCompileUnit can contain a section of source code that is already in the target language, but cannot be rendered to another language.

Defining a namespace

To define a namespace, create a CodeNamespace and assign a name for it using the appropriate constructor or by setting its Name property.

Dim samples As New CodeNamespace("Samples")
[C#]
CodeNamespace samples = new CodeNamespace("Samples");

Importing a namespace

To add a namespace import directive to the namespace, add a CodeNamespaceImport that indicates the namespace to import to the CodeNamespace.Imports collection.

The following code adds an import for the System namespace to the Imports collection of a CodeNamespace named samples:

samples.Imports.Add( New CodeNamespaceImport("System") )
[C#]
samples.Imports.Add( new CodeNamespaceImport("System") );

Linking code elements into the object graph

All code elements that form a CodeDOM graph must be linked to the CodeCompileUnit that is the root element of the tree by a series of references between elements directly referenced from the properties of the root object of the graph. Set an object to a property of a container object to establish a reference from the container object.

The following statement adds the samples CodeNamespace to the Namespaces collection property of the root CodeCompileUnit.

compileUnit.Namespaces.Add( samples )
[C#]
compileUnit.Namespaces.Add( samples );

Defining a type

To declare a class, structure, interface, or enumeration using the CodeDOM, create a new CodeTypeDeclaration, and assign it a name. The following example demonstrates this using a constructor overload to set the Name property:

Dim class1 As New CodeTypeDeclaration("Class1")
[C#]
CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");

To add a type to a namespace, add a CodeTypeDeclaration that represents the type to add to the namespace to the Types collection of a CodeNamespace.

The following example demonstrates how to add a class named class1 to a CodeNamespace named samples:

samples.Types.Add(class1)
[C#]
samples.Types.Add(class1);

Adding class members to a class

The System.CodeDom namespace provides a variety of elements that can be used to represent class members. Each class member can be added to the Members collection of a CodeTypeDeclaration.

Defining a code entry point method for an executable

If you are building code for an executable program, it is necessary to indicate the entry point of a program by creating a CodeEntryPointMethod to represent the method at which program execution should begin.

The following example demonstrates how to define an entry point method that contains a CodeMethodInvokeExpression that calls System.Console.WriteLine to print "Hello World!":

Dim start As New CodeEntryPointMethod()
Dim cs1 As New CodeMethodInvokeExpression( _
    New CodeTypeReferenceExpression("System.Console"), _
    "WriteLine", _
    New CodePrimitiveExpression("Hello World!") )
start.Statements.Add(cs1)  
[C#]
CodeEntryPointMethod start = new CodeEntryPointMethod();
CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression( 
    new CodeTypeReferenceExpression("System.Console"), 
    "WriteLine", new CodePrimitiveExpression("Hello World!") );
start.Statements.Add(cs1);  

The following statement adds the entry point method named Start to the Members collection of class1:

class1.Members.Add( start )
[C#]
class1.Members.Add( start );

Now the CodeCompileUnit named CompileUnit contains the CodeDOM graph for a simple Hello World program. For information on generating and compiling code from a CodeDOM graph, see Generating Source Code and Compiling a Program from a CodeDOM Graph.

More information on building a CodeDOM graph

Representing code that cannot be conveniently represented with CodeDOM elements

The CodeDOM supports the many common types of code elements found in programming languages that support the common language runtime. The CodeDOM was not designed to provide elements to represent all possible programming language features. Code that cannot be represented easily with CodeDOM elements can be encapsulated in a CodeSnippetExpression, a CodeSnippetStatement, a CodeSnippetTypeMember, or a CodeSnippetCompileUnit. However, snippets cannot be translated to other languages automatically by the CodeDOM.

For documentation for the each of the CodeDOM types, see the reference documentation for the System.CodeDom namespace.

For a quick chart to locate the CodeDOM element that represents a specific type of code element, see the CodeDOM Quick Reference.