How to: Create a Class Using CodeDOM

The following procedures illustrate how to create and compile a CodeDOM graph that generates a class containing two fields, three properties, a method, a constructor, and an entry point.

  1. Create a console application that will use CodeDOM code to generate the source code for a class.

    In this example, the generating class is named Sample, and the generated code is a class named CodeDOMCreatedClass in a file named SampleCode.

  2. In the generating class, initialize the CodeDOM graph and use CodeDOM methods to define the members, constructor, and entry point (Main method) of the generated class.

    In this example, the generated class has two fields, three properties, a constructor, a method, and a Main method.

  3. In the generating class, create a language-specific code provider and call its GenerateCodeFromCompileUnit method to generate the code from the graph.

  4. Compile and execute the application to generate the code.

    In this example, the generated code is in a file named SampleCode. Compile and execute that code to see the sample output.

To create the application that will execute the CodeDOM code

  • Create a console application class to contain the CodeDOM code. Define the global fields that are to be used in the class to reference the assembly (CodeCompileUnit) and class (CodeTypeDeclaration), specify the name of the generated source file, and declare the Main method.

    Imports System
    Imports System.Reflection
    Imports System.IO
    Imports System.CodeDom
    Imports System.CodeDom.Compiler
    Imports Microsoft.CSharp
    
    
    
    Class Sample
        Private targetUnit As CodeCompileUnit
        Private targetClass As CodeTypeDeclaration
        Private Const outputFileName As String = "SampleCode.vb" 
    
        Shared Sub Main(ByVal args() As String) 
    
        End Sub 'Main
    End Class 'Sample
    

To initialize the CodeDOM graph

  • In the constructor for the console application class, initialize the assembly and class, and add the appropriate declarations to the CodeDOM graph.

    Public Sub New()
            targetUnit = New CodeCompileUnit()
            Dim samples As New CodeNamespace("CodeDOMSample")
            samples.Imports.Add(New CodeNamespaceImport("System"))
            targetClass = New CodeTypeDeclaration("CodeDOMCreatedClass")
            targetClass.IsClass = True
            targetClass.TypeAttributes = _
                TypeAttributes.Public Or TypeAttributes.Sealed
            samples.Types.Add(targetClass)
            targetUnit.Namespaces.Add(samples)
    
        End Sub 'New
    

To add members to the CodeDOM graph

  • Add fields to the CodeDOM graph by adding CodeMemberField objects to the Members property of the class.

    Public Sub AddFields()
        ' Declare the widthValue field. 
        Dim widthValueField As New CodeMemberField()
        widthValueField.Attributes = MemberAttributes.Private
        widthValueField.Name = "widthValue"
        widthValueField.Type = _
            New CodeTypeReference(GetType(System.Double))
        widthValueField.Comments.Add(New CodeCommentStatement( _
            "The width of the object."))
        targetClass.Members.Add(widthValueField)
    
        ' Declare the heightValue field 
        Dim heightValueField As New CodeMemberField()
        heightValueField.Attributes = MemberAttributes.Private
        heightValueField.Name = "heightValue"
        heightValueField.Type = _
            New CodeTypeReference(GetType(System.Double))
        heightValueField.Comments.Add(New CodeCommentStatement( _
            "The height of the object."))
        targetClass.Members.Add(heightValueField)
    
    End Sub 'AddFields
    
  • Add properties to the CodeDOM graph by adding CodeMemberProperty objects to the Members property of the class.

    Public Sub AddProperties()
        ' Declare the read only Width property. 
        Dim widthProperty As New CodeMemberProperty()
        widthProperty.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final
        widthProperty.Name = "Width"
        widthProperty.HasGet = True
        widthProperty.Type = New CodeTypeReference(GetType(System.Double))
        widthProperty.Comments.Add(New CodeCommentStatement( _
            "The width property for the object."))
        widthProperty.GetStatements.Add(New CodeMethodReturnStatement( _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "widthValue")))
        targetClass.Members.Add(widthProperty)
    
        ' Declare the read-only Height property. 
        Dim heightProperty As New CodeMemberProperty()
        heightProperty.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final
        heightProperty.Name = "Height"
        heightProperty.HasGet = True
        heightProperty.Type = New CodeTypeReference(GetType(System.Double))
        heightProperty.Comments.Add(New CodeCommentStatement( _
            "The Height property for the object."))
        heightProperty.GetStatements.Add(New CodeMethodReturnStatement( _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "heightValue")))
        targetClass.Members.Add(heightProperty)
    
        ' Declare the read only Area property. 
        Dim areaProperty As New CodeMemberProperty()
        areaProperty.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final
        areaProperty.Name = "Area"
        areaProperty.HasGet = True
        areaProperty.Type = New CodeTypeReference(GetType(System.Double))
        areaProperty.Comments.Add(New CodeCommentStatement( _
            "The Area property for the object."))
    
        ' Create an expression to calculate the area for the get accessor 
        ' of the Area property. 
        Dim areaExpression As New CodeBinaryOperatorExpression( _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "widthValue"), _
            CodeBinaryOperatorType.Multiply, _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "heightValue"))
        areaProperty.GetStatements.Add( _
            New CodeMethodReturnStatement(areaExpression))
        targetClass.Members.Add(areaProperty)
    
    End Sub 'AddProperties
    
  • Add a method to the CodeDOM graph by adding a CodeMemberMethod object to the Members property of the class.

    Public Sub AddMethod()
        ' Declaring a ToString method. 
        Dim toStringMethod As New CodeMemberMethod()
        toStringMethod.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Override
        toStringMethod.Name = "ToString"
        toStringMethod.ReturnType = _
            New CodeTypeReference(GetType(System.String))
    
        Dim widthReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "Width")
        Dim heightReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "Height")
        Dim areaReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "Area")
    
        ' Declaring a return statement for method ToString. 
        Dim returnStatement As New CodeMethodReturnStatement()
    
        ' This statement returns a string representation of the width, 
        ' height, and area. 
        Dim formattedOutput As String = "The object:" & Environment.NewLine _
            & " width = {0}," & Environment.NewLine & " height = {1}," _
            & Environment.NewLine & " area = {2}"
        returnStatement.Expression = New CodeMethodInvokeExpression( _
            New CodeTypeReferenceExpression("System.String"), "Format", _
            New CodePrimitiveExpression(formattedOutput), widthReference, _
            heightReference, areaReference)
        toStringMethod.Statements.Add(returnStatement)
        targetClass.Members.Add(toStringMethod)
    
    End Sub 'AddMethod
    
  • Add a constructor to the CodeDOM graph by adding a CodeConstructor object to the Members property of the class.

    Public Sub AddConstructor()
        ' Declare the constructor 
        Dim constructor As New CodeConstructor()
        constructor.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final
    
        ' Add parameters.
        constructor.Parameters.Add( _
            New CodeParameterDeclarationExpression( _
            GetType(System.Double), "width"))
        constructor.Parameters.Add( _
            New CodeParameterDeclarationExpression( _
            GetType(System.Double), "height"))
    
        ' Add field initialization logic 
        Dim widthReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "widthValue")
        constructor.Statements.Add(New CodeAssignStatement( _
            widthReference, New CodeArgumentReferenceExpression("width")))
        Dim heightReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "heightValue")
        constructor.Statements.Add( _
            New CodeAssignStatement(heightReference, _
            New CodeArgumentReferenceExpression("height")))
        targetClass.Members.Add(constructor)
    
    End Sub 'AddConstructor
    
  • Add an entry point to the CodeDOM graph by adding a CodeEntryPointMethod object to the Members property of the class.

    Public Sub AddEntryPoint()
        Dim start As New CodeEntryPointMethod()
        Dim objectCreate As New CodeObjectCreateExpression( _
            New CodeTypeReference("CodeDOMCreatedClass"), _
            New CodePrimitiveExpression(5.3), _
            New CodePrimitiveExpression(6.9))
    
        ' Add the statement: 
        ' "CodeDOMCreatedClass testClass = _ 
        '     new CodeDOMCreatedClass(5.3, 6.9);"
        start.Statements.Add(New CodeVariableDeclarationStatement( _
            New CodeTypeReference("CodeDOMCreatedClass"), _
            "testClass", objectCreate))
    
        ' Creat the expression: 
        ' "testClass.ToString()" 
        Dim toStringInvoke As New CodeMethodInvokeExpression( _
            New CodeVariableReferenceExpression("testClass"), "ToString")
    
        ' Add a System.Console.WriteLine statement with the previous  
        ' expression as a parameter.
        start.Statements.Add(New CodeMethodInvokeExpression( _
            New CodeTypeReferenceExpression("System.Console"), _
            "WriteLine", toStringInvoke))
        targetClass.Members.Add(start)
    
    End Sub 'AddEntryPoint
    

To generate the code from the CodeDOM graph

  • Generate source code from the CodeDOM graph by calling the GenerateCodeFromCompileUnit method.

    Public Sub GenerateVBCode(ByVal fileName As String)
        Dim provider As CodeDomProvider
        provider = CodeDomProvider.CreateProvider("VisualBasic")
        Dim options As New CodeGeneratorOptions()
        Dim sourceWriter As New StreamWriter(fileName)
        Try
            provider.GenerateCodeFromCompileUnit( _
                targetUnit, sourceWriter, options)
        Finally
            sourceWriter.Dispose()
        End Try 
    
    End Sub 'GenerateVBCode
    

To create the graph and generate the code

  1. Add the methods created in the preceding steps to the Main method defined in the first step.

    Shared Sub Main()
            Dim sample As New Sample()
            sample.AddFields()
            sample.AddProperties()
            sample.AddMethod()
            sample.AddConstructor()
            sample.AddEntryPoint()
            sample.GenerateVBCode(outputFileName)
    
        End Sub 'Main
    End Class 'Sample 
    
  2. Compile and execute the generating class.

The following code example shows the code from the preceding steps.

Imports System
Imports System.Reflection
Imports System.IO
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports Microsoft.VisualBasic

' This code example creates a graph using a CodeCompileUnit and   
' generates source code for the graph using the VBCodeProvider. 
Class Sample

    ' Define the compile unit to use for code generation.  
    Private targetUnit As CodeCompileUnit

    ' The only class in the compile unit. This class contains 2 fields, 
    ' 3 properties, a constructor, an entry point, and 1 simple method.  
    Private targetClass As CodeTypeDeclaration

    ' The name of the file to contain the source code. 
    Private Const outputFileName As String = "SampleCode.vb" 

    ' Define the class. 
    Public Sub New()
        targetUnit = New CodeCompileUnit()
        Dim samples As New CodeNamespace("CodeDOMSample")
        samples.Imports.Add(New CodeNamespaceImport("System"))
        targetClass = New CodeTypeDeclaration("CodeDOMCreatedClass")
        targetClass.IsClass = True
        targetClass.TypeAttributes = _
            TypeAttributes.Public Or TypeAttributes.Sealed
        samples.Types.Add(targetClass)
        targetUnit.Namespaces.Add(samples)

    End Sub 'New 

    ' Adds two fields to the class. 
    Public Sub AddFields()
        ' Declare the widthValue field. 
        Dim widthValueField As New CodeMemberField()
        widthValueField.Attributes = MemberAttributes.Private
        widthValueField.Name = "widthValue"
        widthValueField.Type = _
            New CodeTypeReference(GetType(System.Double))
        widthValueField.Comments.Add(New CodeCommentStatement( _
            "The width of the object."))
        targetClass.Members.Add(widthValueField)

        ' Declare the heightValue field 
        Dim heightValueField As New CodeMemberField()
        heightValueField.Attributes = MemberAttributes.Private
        heightValueField.Name = "heightValue"
        heightValueField.Type = _
            New CodeTypeReference(GetType(System.Double))
        heightValueField.Comments.Add(New CodeCommentStatement( _
            "The height of the object."))
        targetClass.Members.Add(heightValueField)

    End Sub 'AddFields

    ' Add three properties to the class. 
    Public Sub AddProperties()
        ' Declare the read only Width property. 
        Dim widthProperty As New CodeMemberProperty()
        widthProperty.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final
        widthProperty.Name = "Width"
        widthProperty.HasGet = True
        widthProperty.Type = New CodeTypeReference(GetType(System.Double))
        widthProperty.Comments.Add(New CodeCommentStatement( _
            "The width property for the object."))
        widthProperty.GetStatements.Add(New CodeMethodReturnStatement( _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "widthValue")))
        targetClass.Members.Add(widthProperty)

        ' Declare the read-only Height property. 
        Dim heightProperty As New CodeMemberProperty()
        heightProperty.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final
        heightProperty.Name = "Height"
        heightProperty.HasGet = True
        heightProperty.Type = New CodeTypeReference(GetType(System.Double))
        heightProperty.Comments.Add(New CodeCommentStatement( _
            "The Height property for the object."))
        heightProperty.GetStatements.Add(New CodeMethodReturnStatement( _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "heightValue")))
        targetClass.Members.Add(heightProperty)

        ' Declare the read only Area property. 
        Dim areaProperty As New CodeMemberProperty()
        areaProperty.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final
        areaProperty.Name = "Area"
        areaProperty.HasGet = True
        areaProperty.Type = New CodeTypeReference(GetType(System.Double))
        areaProperty.Comments.Add(New CodeCommentStatement( _
            "The Area property for the object."))

        ' Create an expression to calculate the area for the get accessor 
        ' of the Area property. 
        Dim areaExpression As New CodeBinaryOperatorExpression( _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "widthValue"), _
            CodeBinaryOperatorType.Multiply, _
            New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "heightValue"))
        areaProperty.GetStatements.Add( _
            New CodeMethodReturnStatement(areaExpression))
        targetClass.Members.Add(areaProperty)

    End Sub 'AddProperties

    ' Adds a method to the class. This method multiplies values stored  
    ' in both fields. 
    Public Sub AddMethod()
        ' Declaring a ToString method. 
        Dim toStringMethod As New CodeMemberMethod()
        toStringMethod.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Override
        toStringMethod.Name = "ToString"
        toStringMethod.ReturnType = _
            New CodeTypeReference(GetType(System.String))

        Dim widthReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "Width")
        Dim heightReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "Height")
        Dim areaReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "Area")

        ' Declaring a return statement for method ToString. 
        Dim returnStatement As New CodeMethodReturnStatement()

        ' This statement returns a string representation of the width, 
        ' height, and area. 
        Dim formattedOutput As String = "The object:" & Environment.NewLine _
            & " width = {0}," & Environment.NewLine & " height = {1}," _
            & Environment.NewLine & " area = {2}"
        returnStatement.Expression = New CodeMethodInvokeExpression( _
            New CodeTypeReferenceExpression("System.String"), "Format", _
            New CodePrimitiveExpression(formattedOutput), widthReference, _
            heightReference, areaReference)
        toStringMethod.Statements.Add(returnStatement)
        targetClass.Members.Add(toStringMethod)

    End Sub 'AddMethod

    ' Add a constructor to the class. 
    Public Sub AddConstructor()
        ' Declare the constructor 
        Dim constructor As New CodeConstructor()
        constructor.Attributes = _
            MemberAttributes.Public Or MemberAttributes.Final

        ' Add parameters.
        constructor.Parameters.Add( _
            New CodeParameterDeclarationExpression( _
            GetType(System.Double), "width"))
        constructor.Parameters.Add( _
            New CodeParameterDeclarationExpression( _
            GetType(System.Double), "height"))

        ' Add field initialization logic 
        Dim widthReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "widthValue")
        constructor.Statements.Add(New CodeAssignStatement( _
            widthReference, New CodeArgumentReferenceExpression("width")))
        Dim heightReference As New CodeFieldReferenceExpression( _
            New CodeThisReferenceExpression(), "heightValue")
        constructor.Statements.Add( _
            New CodeAssignStatement(heightReference, _
            New CodeArgumentReferenceExpression("height")))
        targetClass.Members.Add(constructor)

    End Sub 'AddConstructor

    ' Add an entry point to the class. 
    Public Sub AddEntryPoint()
        Dim start As New CodeEntryPointMethod()
        Dim objectCreate As New CodeObjectCreateExpression( _
            New CodeTypeReference("CodeDOMCreatedClass"), _
            New CodePrimitiveExpression(5.3), _
            New CodePrimitiveExpression(6.9))

        ' Add the statement: 
        ' "CodeDOMCreatedClass testClass = _ 
        '     new CodeDOMCreatedClass(5.3, 6.9);"
        start.Statements.Add(New CodeVariableDeclarationStatement( _
            New CodeTypeReference("CodeDOMCreatedClass"), _
            "testClass", objectCreate))

        ' Creat the expression: 
        ' "testClass.ToString()" 
        Dim toStringInvoke As New CodeMethodInvokeExpression( _
            New CodeVariableReferenceExpression("testClass"), "ToString")

        ' Add a System.Console.WriteLine statement with the previous  
        ' expression as a parameter.
        start.Statements.Add(New CodeMethodInvokeExpression( _
            New CodeTypeReferenceExpression("System.Console"), _
            "WriteLine", toStringInvoke))
        targetClass.Members.Add(start)

    End Sub 'AddEntryPoint

    ' Generate Visual Basic source code from the compile unit. 
    Public Sub GenerateVBCode(ByVal fileName As String)
        Dim provider As CodeDomProvider
        provider = CodeDomProvider.CreateProvider("VisualBasic")
        Dim options As New CodeGeneratorOptions()
        Dim sourceWriter As New StreamWriter(fileName)
        Try
            provider.GenerateCodeFromCompileUnit( _
                targetUnit, sourceWriter, options)
        Finally
            sourceWriter.Dispose()
        End Try 

    End Sub 'GenerateVBCode

    ' Create the CodeDOM graph and generate the code. 
    Shared Sub Main()
        Dim sample As New Sample()
        sample.AddFields()
        sample.AddProperties()
        sample.AddMethod()
        sample.AddConstructor()
        sample.AddEntryPoint()
        sample.GenerateVBCode(outputFileName)

    End Sub 'Main
End Class 'Sample 

When the preceding example is compiled and executed, it produces the following source code.

'-------------------------------------------------------------------------- 
' <auto-generated> 
'     This code was generated by a tool. 
'     Runtime Version:2.0.50727.42 

'     Changes to this file may cause incorrect behavior and will be lost if 
'     the code is regenerated. 
' </auto-generated> 
'-------------------------------------------------------------------------- 

Option Strict Off
Option Explicit On 

Imports System

Namespace CodeDOMSample

    Public NotInheritable Class CodeDOMCreatedClass

        'The width of the object. 
        Private widthValue As Double 

        'The height of the object. 
        Private heightValue As Double 

        Public Sub New(ByVal width As Double, ByVal height As Double)
            MyBase.New 
            Me.widthValue = width
            Me.heightValue = height
        End Sub 

        'The width property for the object. 
        Public ReadOnly Property Width() As Double 
            Get 
                Return Me.widthValue
            End Get 
        End Property 

        'The Height property for the object. 
        Public ReadOnly Property Height() As Double 
            Get 
                Return Me.heightValue
            End Get 
        End Property 

        'The Area property for the object. 
        Public ReadOnly Property Area() As Double 
            Get 
                Return (Me.widthValue * Me.heightValue)
            End Get 
        End Property 

        Public Overrides Function ToString() As String 
            Return String.Format("The object:"& _
                Global.Microsoft.VisualBasic.ChrW(13)& _
                Global.Microsoft.VisualBasic.ChrW(10)& _
                " width = {0},"&Global.Microsoft.VisualBasic.ChrW(13)& _
                Global.Microsoft.VisualBasic.ChrW(10)& _
                " height = {1},"&Global.Microsoft.VisualBasic.ChrW(13)& _
                Global.Microsoft.VisualBasic.ChrW(10)&" area = {2}", _
                Me.Width, Me.Height, Me.Area)
        End Function 

        Public Shared Sub Main()
            Dim testClass As CodeDOMCreatedClass = _
                New CodeDOMCreatedClass(5.3, 6.9)
            System.Console.WriteLine(testClass.ToString)
        End Sub 
    End Class 
End Namespace

The generated source code produces the following output when compiled and executed.

The object:
 width = 5.3,
 height = 6.9,
 area = 36.57

  • This code example requires the FullTrust permission set to execute successfully.

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft