Using CodeDom to create language-independent code for instantiating and initializing object graphs, as the Designer does, is quite simple. Here are some of the basic steps:
Creating an object
In C#, a System.Drawing.Size object is instantiated like this:
new Size(640, 400)
To create a CodeDom tree for the same expression is not too much more work:
CodeExpression newSizeExpr = new CodeObjectCreateExpression(new CodeTypeReference(“System.Drawing.Size”),
new CodePrimitiveExpression(640), new CodePrimitiveExpression(400));
The first parameter is, clearly, a CodeTypeReference (note that the fully-qualified name is necessary; there’s no using in CodeDom) of the desired type, and the remaining parameters are the arguments to the constructor to be used. Whether the arguments you gave can be bound to a valid constructor won’t be checked until the tree is processed by a provider, so be careful! CodeDom won’t stop you from writing, instead,
new CodePrimitiveExpression(“bigger than the biggest thing ever and then some”));
Storing the object
There’s not much point creating an object if we don’t put it someplace. Suppose the Size object created in the previous expression is the initialization of the ClientSize property of a Form. In the form’s initialization method, you’ll see a line of code like:
ClientSize = new Size(640,400)
We already have the expression for the object creation stored in newSizeStmt, so creating the corresponding CodeStatement is simple:
CodeExpression thisExpr = new CodeThisReferenceExpression()
CodeStatement clientSizeStmt = new CodeAssignStatement(
new CodePropertyReferenceExpression(thisExpr, “ClientSize”),
newSizeExpr)
A CodeAssignStatement has, naturally, a left-hand and right-hand side expression. On the left-hand side we have a CodePropertyReferenceExpression, created from an object expression (in this case just this) and a property name given as a string. On the right-hand side is newSizeExpr. Of course, the CodeDom tree for the whole statement could be generated in a single line of code, at the expense of some readability.
There are two things to note here:
One of CodeDom’s uses, as we can see from this example, is to provide a fairly simple, maintainable way to create and store boilerplate code that can be parameterized and reused in different settings and even different languages.