AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1009&pId=-1
Using CodeDOM in .NET 2.0
page
by Uday Denduluri
Feedback
Average Rating: 
Views (Total / Last 10 Days): 41667/ 72

Introduction

CodeDOM is a very powerful Application Programming Interface (API) that is available with Microsoft .NET 2.0.  This API can do wonders for you by generating code on the fly.  This article takes a look at this technology and explains it with code examples wherever appropriate.

What is CodeDOM?

CodeDOM is an API that helps in creating and compiling a programming structure at Runtime. Creating a programming structure involves creation of Namespace, Type – Class, Interface and even methods at the Runtime.  The implementation of CodeDOM can be divided in the two ways shown below.

·         Compiling or Building the Programs at the Runtime (Like a Normal compiler)

·         Using CodeDOM for generating a Program structure

Compiling or Building the Programs at the Runtime

Probably the biggest change in .NET 2.0 Framework is the usage of CodeDomProvider extensively.  This is an abstract class that comes under the namespace System.CodeDom.Compiler.  This class has various methods that help us to compile a code and also generate the code.  All the language providers of .Net inherit this class.  The CSharpCodeProvider class comes under the Microsoft.CSharp namespace and inherits this class and implements all the methods accordingly.

Let us now see how a code is executed with a complete code.

The Code snippet below explains how to compile a code at runtime using CodeDOM.  It explains all the basic classes and methods that help to achieve the same.  The code uses namespaces like “System.CodeDom,” “System.CodeDom.Compiler” and “Microsoft.CSharp.”  The code below assumes that the reader understands the syntax of C# language and is well versed with the basic programming techniques.

Listing 1

CodeDomProvider codeDomProvider = new CSharpCodeProvider();
CompilerParameters compilerParameters = new CompilerParameters();
compilerParameters.GenerateExecutable = false;
string[]code =
{
  @"namespace CodeDomTest1 { class Class1
  {
//[STAThread]
    static void Main(string[]args)
    {
      string str = "" Output "";
      Console.WriteLine(str);
    }
  }
}
  "};
CompilerResults compilerResults =
 codeDomProvider.CompileAssemblyFromSource(compilerParameters, code);
CompilerErrorCollection compilerErrorCollection =
 compilerResults.Errors;

CompilerParameters is a class from System.CodeDOM.Compiler namespace that represents the parameters used to invoke a compiler.  We can set all the compiler parameters using this class. CompilerResults is a class that encapsulates all the results of the output after compilation. CodeDomProvider does that actual initiation of compiling the code by the method CompileAssemblyFromSource.  It takes two parameters, the code as an array of strings and the compiler options by using the object of CompilerParameters.  It returns the results as a type CompilerResults.

Using CodeDOM technology for generating the Program structure

All CodeDOM programs start out with the creation of ICodeGenerator for the target language.  The following code shows the creation of the ICodeGenerator for C#.

The code snippet below explains how to create a program structure at runtime using CodeDom.  It explains all the basic classes and methods that help to achieve the same.  The code uses namespaces like “System.CodeDom,” “System.CodeDom.Compiler” and “Microsoft.CSharp.”  The code below assumes that the reader understands the syntax of C# language and is well versed with the basic programming techniques.

Listing 2

ICodeGenerator cg =new CSharpCodeProvider().CreateGenerator();
...
CSharpCodeProvider cdp = new CSharpCodeProvider();
cg = cdp.CreateGenerator();

The ICodeGenerator is used to generate the actual code once a CodeDOM tree is built.  To begin building our tree, we need to start with a CodeNamespace object.  This object will contain any types and import directives.  With the CodeNamespace object we can begin the tree.  For the following sample, several CodeNamespaceImport objects are used to generate import directives for commonly used namespaces.  The sample also needs to generate a class construct and this is done by using a CodeTypeDeclaration and setting the IsClass property to true.  The following code demonstrates these concepts.

Listing 3

CodeNamespace cnamespace = new CodeNamespace("Microsoft.Samples");
cnamespace.Imports.Add (new CodeNamespaceImport ("System") );
...
CodeTypeDeclaration co = new CodeTypeDeclaration (typeName +"List");
co.IsClass = true;
cnamespace.Types.Add (co);

At the end of the previous example, the class type definition is added to the Types collection of the CodeNamespace object.  This is how a CodeDOM tree is built starting with a CodeNamespace object and working down through classes to class members.  Class members in turn contain different types of code statements and expressions.  Once the entire tree is built, the entire source tree can be written with a call to GenerateCodeFromNamespace, a method on ICodeGenerator.  The methods being passed are the CodeNamespace object and a TextWriter.

baseCompiler.GenerateCodeFromNamespace (cnamespace, w, null);
Applications that can be developed using CODEDOM

It is a common question that arises in everyone’s mind: What kind of applications of CodeDOM API help us develop or where can we apply CodeDOM in true business sense?  These questions are quite rational from a programmer who is used to coding.  To understand the applicability of the CodeDOM API, we need to understand problems associated with the current model of developing applications.

·         Developing a Product in a generic way is a tough job these days.  This is because of implementing the business customizations from customer to customer is expensive to integrate into the application.

·         Extending features of a product with respect to customer is a tedious job.

·         Handling the changes to the business rules is also an expensive job.

CodeDOM is one of the solutions for all of the above problems.  Using CodeDOM we can develop code dynamically and integrate it into the products.  All the business rules can be customized without much rework, thus bringing down the costs of change requests.  Even customers can add their own code to extend a feature that suits their applications.  All we need to do is have a placeholder for providing the extensibility.

CodeDOM in .NET Framework 2.0

Programmers who are used to developing applications in CodeDOM (.NET Framework 1.x) will encounter a warning in .NET Framework 2.0: “System.CodeDom.Compiler.CodeDomProvider.CreateCompiler() is obsolete: Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class.”   Problems may be with the code given below.

The Code snippet below explains the issue of .NET 1.x code having problems in .NET 2.0.  It explains the enriched functionality of the CodeDomProvider class.  The code uses namespaces like “System.CodeDom,” “System.CodeDom.Compiler” and “Microsoft.CSharp.”  The code below assumes that the reader understands the syntax of C# language and is well versed with the basic programming techniques.

Listing 4

ICodeCompiler iCodeCompiler = new CSharpCodeProvider().CreateCompiler();
iCodeCompiler.CompileAssemblyFromSource(compilerParameters, strcode);

In .NET Framework 2.0, CodeDomProvider itself encapsulates all of the iCodeCompiler methods. Therefore, we better use a reference of the CodeDOM provider and use it as shown below.

CodeDomProvider  codeDomProvider = new CSharpCodeProvider();
CompilerResults compilerResults =
 codeDomProvider.CompileAssemblyFromSource(compilerParameters, code);

The ICodeCompiler is an obsolete method and a programmer should try to avoid it.

Understanding the importance of the CodeDomProvider class

First, let us identify some of the functions of CodeDomProvider class in a tabular format.

S NO  

Method Name / Property Name         

Description

1

CompileAssemblyFromSource

Compiles an array of source code strings.

2

CreateCompiler

 

Creates an ICodeCompiler that can be used for compilation and returns it.

3

CreateProvider

Creates a CodeDomProvider and returns it.

4

CompileAssemblyFromDom

Compiles an assembly based on the System.CodeDom trees contained in the specified array of System.CodeDom.CodeCompileUnit objects using the specified compiler

 

5

CompileAssemblyFromFile

Compiles an assembly by taking the name of the file.

6

GetLanguageFromExtension

Returns a language name associated with the specified file name extension as configured in the System.CodeDom.Compiler.CodeDomProvider compiler configuration section.

 

7

GetCompilerInfo

Returns the language provider and compiler configuration settings for the specified language.

                  

As we can see from the tabular format, we have methods of two types: Creating a compiler and compiling the source code from an existing compiler.  We can identify here that CodeDomProvider encapsulates the creation part and the compilation part.  Therefore, CodeDomProvider is a vital class in the architecture of CodeDom 2.0.

References
Conclusion

To sum it up, CodeDom is an API that gives the ability to create a programming structure of namespaces, objects, and programming constructs by adding items to different collections. CodeDom will be used extensively in the future for providing the Dynamic code compilation for applications whose business rules are susceptible to changes.  CodeDom is the most efficient way a product’s features can be further enhanced.



©Copyright 1998-2021 ASPAlliance.com  |  Page Processed at 2021-02-26 11:15:01 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search