Part IV: The Structure of the Code Document Object Model
Please note that the following document uses UML style notations for describing inter-type relations.
The following classes, all of which are placed in the System.dll file and are inside the System.CodeDom namespace, make up the Code DOM:
This class is the highest type in the Code DOM hierarchy. This class contains a complete graph of objects that can become a document.
We can compare this class to the better known
System.Xml.XmlDocument class in the XML Document Object Model Framework implementation.
This class represents a namespace that will be used for the types that we declare.
One CodeCompileUnit object may contain one or more CodeNamespace objects.
This class represents a type. This means that the class can represent an
Enum,
Struct,
Class or
Interface.
Inheritance and interface implementation is easily set using the
BaseTypes property.
One CodeNamespace object may contain one or more CodeTypeDeclaration objects.
This class is the base class for all classes representing different types of type members. For instance, the CodeMemberField class, which represents a field, inherits from this type.
One CodeTypeDeclaration object may contain one or more CodeTypeMember objects.
Note that since CodeTypeDeclaration inherits from CodeTypeMember, it can also be a member and would appear as an inner type.
The following classes inherit from CodeTypeMember:
- CodeMemberEvent - This class represents a member that is an event.
- CodeMemberField - This class represents a member that is a field. This class can also be used to describe values for an Enum.
- CodeMemberMethod - This is the general method class for a type. However, there are three types of specialized methods:
- CodeMemberProperty - This class represents a property.
Note that this member does not have one Statements property, but two: GetStatements and SetStatements.
Prior to adding statements to either, remember to set the HasGet and HasSet properties respectively.
There are many other classes that can represent members, but I find these to be of most interest.
Comment Classes
These classes are in charge of comments in the code document. For each comment, one can decide if it is an Xml Comment or a Simple Comment.
These classes are:
Statements and Expressions
All
statements in CodeDOM inherit from the
CodeStatement class.
All
expressions in CodeDOM inherit from the
CodeExpression class. An expression can become a statement if we use it in the
CodeExpressionStatement class.
All classes inheriting from these classes will be explained in the next parts.
Example
The following fragment of code creates an object graph from the types explained in this part.
Some of the properties used here, such as the Attributes property, will be discussed in the next chapter.
CodeCompileUnit unit = new CodeCompileUnit();
CodeNamespace nameSpace = new CodeNamespace("CodeDomArticle");
CodeTypeDeclaration type = new CodeTypeDeclaration("PartIV");
#region Field
CodeMemberField field = new CodeMemberField(typeof(int), "m_IntegerMember");
type.Members.Add(field);
#endregion
#region Static Constructor
CodeTypeConstructor typeConstructor = new CodeTypeConstructor();
type.Members.Add(typeConstructor);
#endregion
#region Instance Constructor
CodeConstructor constructor = new CodeConstructor();
constructor.Attributes &= ~MemberAttributes.AccessMask;
constructor.Attributes |= MemberAttributes.Public;
type.Members.Add(constructor);
#endregion
#region Property (with comment)
CodeMemberProperty property = new CodeMemberProperty();
property.Attributes &= ~MemberAttributes.AccessMask;
property.Attributes |= MemberAttributes.Public;
property.Name = "MyProperty";
property.Type = new CodeTypeReference(typeof(int));
property.HasGet = false;
property.HasSet = true;
property.Comments.Add(new CodeCommentStatement("You are not allowed to get the value from this property. Hah!"));
type.Members.Add(property);
#endregion
#region Event
CodeMemberEvent myEvent = new CodeMemberEvent();
myEvent.Attributes &= ~MemberAttributes.AccessMask;
myEvent.Attributes |= MemberAttributes.Public;
myEvent.Type = new CodeTypeReference(typeof(EventHandler));
myEvent.Name = "MyEvent";
type.Members.Add(myEvent);
#endregion
#region Method
CodeMemberMethod method = new CodeMemberMethod();
method.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
method.Attributes |= MemberAttributes.Public | MemberAttributes.Static;
method.Name = "MyMethod";
method.Parameters.Add(new CodeParameterDeclarationExpression("PartIV", "part"));
type.Members.Add(method);
#endregion
#region Entry Point
CodeEntryPointMethod entryPoint = new CodeEntryPointMethod();
type.Members.Add(entryPoint);
#endregion
nameSpace.Types.Add(type);
unit.Namespaces.Add(nameSpace);
Output from the CSharpCodeGenerator for the object graph:
namespace CodeDomArticle
{
public class PartIV
{
private int m_IntegerMember;
static PartIV()
{
}
public PartIV()
{
}
// You are not allowed to get the value from this property. Hah!
public int MyProperty
{
set
{
}
}
public event System.EventHandler MyEvent;
public static void MyMethod(PartIV part)
{
}
public static void Main()
{
}
}
}
Output from the VBCodeGenerator for the object graph:
Option Strict Off
Option Explicit On
Namespace CodeDomArticle
Public Class PartIV
Private m_IntegerMember As Integer
Shared Sub New()
End Sub
Public Sub New()
MyBase.New
End Sub
'You are not allowed to get the value from this property. Hah!
Public WriteOnly Property MyProperty As Integer
Set
End Set
End Property
Public Event MyEvent As System.EventHandler
Public Shared Sub MyMethod(ByVal part As PartIV)
End Sub
Public Shared Sub Main()
End Sub
End Class
End Namespace