Introduction:
This is a continuation to my earlier post C#-The Language : A Step Ahead Series-Part-II
The following code snippet showed the power of CODE DOM:
/* This Example is a part of different
* examples shown in Book:
* C#2005 Beginners: A Step Ahead
* Written by: Gaurav Arora
* Reach at : msdotnetheaven*/
// File name : CodeDomExpl.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.IO;
namespace CSharp.AStepAhead.CodeDomExpl
{
public class CodeDomExpl
{
public static void Main()
{
Console.Clear();
Console.Write("This will create a simple Console aplication\n");
Console.Write("\n Enter Namespace: ");
string nmSpace = Console.ReadLine();
Console.Write("\n Enter Class file name: ");
string fName = Console.ReadLine();
Console.Write("\n Enter Output file name: ");
string oFname = Console.ReadLine();
Console.Write("\n Enter Your message: ");
string msg = Console.ReadLine();
if (nmSpace.Length == 0)
nmSpace = "CSharp.AStepAhead.CodeDomExpl";
if (fName.Length==0)
fName = "CodeDomExpl.cs";
if (oFname.Length==0)
oFname ="CodeDomExpl.exe";
if (msg.Length==0)
msg = "Hello! I am created using CodeDom i.e. Code Document Object Model.";
//Validate enteries
nmSpace = CodeDomExpl.chkValid(nmSpace,0);
fName = CodeDomExpl.chkValid(fName,1);
oFname = CodeDomExpl.chkValid(oFname,2);
msg = CodeDomExpl.chkValid(msg,3);
//create an instance of the class
GenerateConsoleApp oC = new GenerateConsoleApp(nmSpace,fName,oFname,msg);
oC.CreateCode();
Console.WriteLine("\nApplication crated :\nSource File Name :{0}\nExecutable File Name :{1}", fName, oFname);
Console.ReadLine();
return;
}
public static string chkValid(string str,int id)
{
string newStr=string.Empty;
string filePath = @"F:\myWrittings\CSharpBook\Source Codes\CodeDomApplications\";
switch (id)
{
case 3: //message
{
newStr = str;
break;
}
case 2: //output file name
{
int i = str.IndexOf(".");
newStr = (i > 0) ? filePath + str.Substring(0, i) + ".exe" : filePath + str + ".exe";
break;
}
case 1: //class file name
{
int i = str.IndexOf(".");
newStr = (i > 0) ? filePath + str.Substring(0, i) + ".cs" : filePath + str + ".cs";
break;
}
case 0: //namespace
{
int i = str.IndexOf(".");
newStr = "CSharp.AStepAhead.";
newStr += (i > 0) ? str.Substring(0, i) : str;
break;
}
}
return newStr;
}
}
public class GenerateConsoleApp
{
public string nameSpace;
public string sourceFile;
public string executingFile;
public string customMessage;
public GenerateConsoleApp()
{
}
public GenerateConsoleApp(string nmSpace, string csFile,string exeFile,string msg)
{
nameSpace = nmSpace;
sourceFile = csFile;
executingFile = exeFile;
customMessage = msg;
}
public void CreateCode()
{
CodeCompileUnit unit = GenerateCode();
// Set up options for source code style
CodeGeneratorOptions opts = new CodeGeneratorOptions();
opts.BracingStyle = "C";
opts.IndentString = "\t";
// Create code generator and write code file
CSharpCodeProvider cscp = new CSharpCodeProvider();
ICodeGenerator gen = cscp.CreateGenerator();
StreamWriter sw = new StreamWriter(sourceFile);
gen.GenerateCodeFromCompileUnit(unit, sw, opts);
sw.Close();
CompilerParameters compilerParams = new CompilerParameters();
compilerParams.GenerateExecutable = true;
compilerParams.OutputAssembly = executingFile;
ICodeCompiler compiler = cscp.CreateCompiler();
compiler.CompileAssemblyFromFile(compilerParams, sourceFile);
}
private CodeCompileUnit GenerateCode()
{
CodeEntryPointMethod objMainMethod = new CodeEntryPointMethod();
objMainMethod.Name = "Main";
// generate this expression: Console
CodeTypeReferenceExpression consoleType = new CodeTypeReferenceExpression();
consoleType.Type = new CodeTypeReference(typeof(Console));
// Set up the argument list to pass to Console.WriteLine()
CodeExpression[] writeLineArgs = new CodeExpression[1];
CodePrimitiveExpression arg0 = new CodePrimitiveExpression(customMessage);
writeLineArgs[0] = arg0;
// generate this statement: Console.WriteLine(message)
CodeMethodReferenceExpression writeLineRef = new CodeMethodReferenceExpression(consoleType, "WriteLine");
CodeMethodInvokeExpression writeLine = new CodeMethodInvokeExpression(writeLineRef, writeLineArgs);
// generate this statement: Console.ReadLine()
CodeMethodReferenceExpression readLineRef = new CodeMethodReferenceExpression(consoleType, "ReadLine");
CodeMethodInvokeExpression readLine = new CodeMethodInvokeExpression(readLineRef);
// Add Main() method to a class
CodeTypeDeclaration theClass = new CodeTypeDeclaration();
theClass.Members.Add(objMainMethod);
string className = string.Empty;
//retrieve actual class name
int j = sourceFile.LastIndexOf(@"\");
int k = sourceFile.IndexOf(".");
className = sourceFile.Substring(j + 1, k - j - 1);
// Add both the code of WriteLine and Readline
objMainMethod.Statements.Add(writeLine);
objMainMethod.Statements.Add(readLine);
// Add namespace and add class
CodeNamespace ns = new CodeNamespace(nameSpace);
ns.Imports.Add(new CodeNamespaceImport("System"));
ns.Types.Add(theClass);
// Generate the Compile Unit
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(ns);
return unit;
}
}
}
To represent source code, CodeDOM elements are linked to each other to form a data structure known as a CodeDOM graph, which models the structure of some source code.
The System.CodeDom namespace defines types that can represent the logical structure of source code, independent of a specific programming language.
Simply, it is an object model which represents actually source code. It is designed to be language independent.
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.
No comments:
Post a Comment