Blue Theme Orange Theme Green Theme Red Theme
 
Discover the top 5 tips for understanding .NET Interop
Home | Forums | Videos | Advertise | Certifications | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
Team Foundation Server Hosting
Search :       Advanced Search »
Home » C# Assemblies » Dynamically creating Applications using System.CodeDom

Dynamically creating Applications using System.CodeDom

The article provides an insight on how to create and compile assemblies dynamically.

Page Views : 27966
Downloads : 419
Rating :
 Rate it
Level : Intermediate
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
DynamicAssemblies.zip
 
 
Nevron Chart
Become a Sponsor
 Tag Cloud
 Latest Jobs
More ... 
 Latest Interview Questions
More ... 

Introduction

The System.CodeDom namespace in .net allows the users to dynamically compile and create assemblies. This concept is used by ASP.NET internally. The article provides an insight on how to create assemblies dynamically.

The following are the list of classes, which would be used to create the assembly:

  • CodeNamespace
  • CodeTypeDeclaration
  • CodeCompileUnit
  • CodeEntryPointMethod
  • CodeMemberField
  • CodeMemberProperty
  • CodeMemberMethod
  • CodeParameterDeclarationExpression
  • CodeCompileUnit
  • CompilerParameters
  • CodeSnippetExpression
  • CodeExpressionStatement

Step 1:

Add the following namespace declarations,

using System;
using
System.CodeDom;
using System.CodeDom.Compiler;

The System.Codedom namespace contains the classes/types necessary to create assemblies at runtime. The above-mentioned classes are contained within this namespace.

Step 2: Create the following class,

public class CCodeGenerator
{
CodeNamespace mynamespace;
CodeTypeDeclaration myclass;
CodeCompileUnit myassembly;
}

Any code created from Step 3 to Step 10 must reside in the CcodeGenerator class. For clarity and explanation sake, the article has fragmented the code into pieces.

Step 3:

The CodeNamespace class is used to add/create namespaces. The name of the namespace can be passed through the constructor of the class.

public void CreateNamespace()
{
mynamespace =
new
CodeNamespace("mynamespace");
}

Step 4: Using the mynamespace object, add the list of all namespaces that are used by the assembly.

public void CreateImports()
{
mynamespace.Imports.Add(
new
CodeNamespaceImport("System"));
mynamespace.Imports.Add(
new
CodeNamespaceImport("System.Drawing"));
mynamespace.Imports.Add(
new
CodeNamespaceImport("System.Windows.Forms"));
}

Step 5: Create a class inside the namespace.

public void CreateClass()
{
myclass =
new
CodeTypeDeclaration();
//Assign a name for the class
myclass.Name = "CMyclass";
myclass.IsClass =
true
;
//Set the Access modifier.
myclass.Attributes = MemberAttributes.Public;
//Add the newly created class to the namespace
mynamespace.Types.Add(myclass);
}

Step 6: Create a member and add it to the newly created class.

public void CreateMember()
{
//Provide the type and variable name
CodeMemberField mymemberfield = new CodeMemberField(typeof
(System.String),"strMessage");
//Add the member to the class
myclass.Members.Add(mymemberfield);
}

Step 7: Create a property (with get and set) and add it to the class

public void CreateProperty()
{
CodeMemberProperty mymemberproperty =
new
CodeMemberProperty();
//Name of the property
mymemberproperty.Name = "Message";
//Data type of the property
mymemberproperty.Type = new CodeTypeReference(typeof
(System.String));
//Access modifier of the property
mymemberproperty.Attributes = MemberAttributes.Public;
//Add the property to the class
myclass.Members.Add(mymemberproperty);
//Add the code-snippets to the property.
//If required, we can also add some custom validation code.
//using the CodeSnippetExpression class.
//Provide the return <propertyvalue> statement-For getter
CodeSnippetExpression getsnippet = new
CodeSnippetExpression("return strMessage");
//Assign the new value to the property-For setter
CodeSnippetExpression setsnippet = new
CodeSnippetExpression("strMessage=value");
//Add the code snippets into the property
mymemberproperty.GetStatements.Add(getsnippet);
mymemberproperty.SetStatements.Add(setsnippet);
}

Step 8:

Create a method. Please take utmost care when assigning values to the CodeSnippetExpression class, as any statement provided must be not have any syntax error(s). Since the assembly would be created at runtime (dynamically), the compiler would simply throw all

Compile-time error(s) and we don't have any prudent means to find and eliminate the error.

public void CreateMethod()
{
//Create an object of the CodeMemberMethod
CodeMemberMethod mymethod = new
CodeMemberMethod();
//Assign a name for the method.
mymethod.Name = "AddNumbers";
//create two parameters
CodeParameterDeclarationExpression cpd1 = new CodeParameterDeclarationExpression(typeof(int
),"a");
CodeParameterDeclarationExpression cpd2 =
new CodeParameterDeclarationExpression(typeof(int
),"b");
//Add the parameters to the method.
mymethod.Parameters.AddRange(new
CodeParameterDeclarationExpression[] {cpd1, cpd2});
//Provide the return type for the method.
CodeTypeReference ctr = new CodeTypeReference(typeof
(System.Int32));
//Assign the return type to the method.
mymethod.ReturnType = ctr;
//Provide definition to the method (returns the sum of two //numbers)

CodeSnippetExpression snippet1=
new CodeSnippetExpression("System.Console.WriteLine(\" Adding :\" + a + \" And \" + b )");
//return the value
CodeSnippetExpression snippet2 = new
CodeSnippetExpression("return a+b");
//Convert the snippets into Expression statements.
CodeExpressionStatement stmt1 = new
CodeExpressionStatement(snippet1);
CodeExpressionStatement stmt2 =
new
CodeExpressionStatement(snippet2);
//Add the expression statements to the method.
mymethod.Statements.Add(stmt1);
mymethod.Statements.Add(stmt2);
//Provide the access modifier for the method.
mymethod.Attributes = MemberAttributes.Public;
//Finally add the method to the class.
myclass.Members.Add(mymethod);
}

Step 9: Create a main method (Entry point for the assembly);

public void CreateEntryPoint()
{
//Create an object and assign the name as "Main"
CodeEntryPointMethod mymain = new
CodeEntryPointMethod();
mymain.Name = "Main";
//Mark the access modifier for the main method as Public and //static
mymain.Attributes = MemberAttributes.Public | MemberAttributes.Static;
//Provide defenition to the main method.
//Create an object of the "Cmyclass" and invoke the method
//by passing the required parameters.
CodeSnippetExpression exp1 = new
CodeSnippetExpression("CMyclass x = new CMyclass()");
//Assign value to our property
CodeSnippetExpression exp2 = new
CodeSnippetExpression("x.Message=\"Hello World \"");
//Print the value in the property
CodeSnippetExpression exp3 = new
CodeSnippetExpression("Console.WriteLine(x.Message)");
//Invode the method
CodeSnippetExpression exp4 = new
CodeSnippetExpression("Console.WriteLine(\"Answer: {0}\",x.AddNumbers(10,20))");
CodeSnippetExpression exp5 =
new
CodeSnippetExpression("Console.ReadLine()");
//Create expression statements for the snippets
CodeExpressionStatement ces1 = new
CodeExpressionStatement(exp1);
CodeExpressionStatement ces2 =
new
CodeExpressionStatement(exp2);
CodeExpressionStatement ces3 =
new
CodeExpressionStatement(exp3);
CodeExpressionStatement ces4 =
new
CodeExpressionStatement(exp4);
CodeExpressionStatement ces5 =
new
CodeExpressionStatement(exp5);
//Add the expression statements to the main method.
mymain.Statements.Add(ces1);
mymain.Statements.Add(ces2);
mymain.Statements.Add(ces3);
mymain.Statements.Add(ces4);
mymain.Statements.Add(ces5);
//Add the main method to the class
myclass.Members.Add(mymain);
}

Step 10: Compile the class and create the assembly.

public void SaveAssembly()
{
//Create a new object of the global CodeCompileUnit class.
myassembly = new
CodeCompileUnit();
//Add the namespace to the assembly.
myassembly.Namespaces.Add(mynamespace);
//Add the following compiler parameters. (The references to the //standard .net dll(s) and framework library).
CompilerParameters comparam = new CompilerParameters(new string
[] {"mscorlib.dll"});
comparam.ReferencedAssemblies.Add("System.dll");
comparam.ReferencedAssemblies.Add("System.Drawing.dll"); comparam.ReferencedAssemblies.Add("System.Windows.Forms.dll");
//Indicates Whether the compiler has to generate the output in //memory
comparam.GenerateInMemory = false
;
//Indicates whether the output is an executable.
comparam.GenerateExecutable = true
;
//provide the name of the class which contains the Main Entry //point method
comparam.MainClass = "mynamespace.CMyclass";
//provide the path where the generated assembly would be placed
comparam.OutputAssembly = @"c:\temp\HelloWorld.exe";
//Create an instance of the c# compiler and pass the assembly to //compile
Microsoft.CSharp.CSharpCodeProvider ccp = new
Microsoft.CSharp.CSharpCodeProvider();
ICodeCompiler icc = ccp.CreateCompiler();
//The CompileAssemblyFromDom would either return the list of
//compile time errors (if any), or would create the
//assembly in the respective path in case of successful //compilation
CompilerResults compres = icc.CompileAssemblyFromDom(comparam,myassembly);
if (compres == null
|| compres.Errors.Count>0)
{
for (int
i=0; i<compres.Errors.Count;i++)
{
Console.WriteLine(compres.Errors[i]);
}
}
 

Step 11: Create a test component to create the assembly.

using System;
namespace DynamicAssemblies
{
class
testCodeDom
{
[STAThread]
static void Main(string
[] args)
{
CCodeGenerator cg =
new
CCodeGenerator();
cg.CreateNamespace();
cg.CreateImports();
cg.CreateClass();
cg.CreateMember();
cg.CreateProperty();
cg.CreateMethod();
cg.CreateEntryPoint();
cg.SaveAssembly();
Console.ReadLine();
}
}
}

The HelloWorld.exe would be created in the mentioned path. The output of the assembly would be as follows:

Conclusion

The facility to dynamically create assemblies would be of immense use, when developing real-world applications that demand a great amount of flexibility and scalability.

Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.
Login to add your contents and source code to this article
 [Top] Rate this article
 
 About the author
 
Subburam Karthikeyan
I am Karthikeyan.S, I am working as a software engineer in Mascon Global Ltd. for 3 years in .Net technologies. I have completed my MCAD (Microsoft certified application developer) exam. I have a real passion for c#.net.
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Discover the Top 5 .NET Memory Management Fundamentals
To write the best .NET code, you need to know exactly how the .NET framework really manages memory. Ricky Leeks presents the Top 5 fundamental facts of .NET memory management. Learn more.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
Nevron Chart
Become a Sponsor
 Comments
superb work by Nirosh On November 2, 2006

This is very detail full and the best I can find on this topic..

 

Nirosh

Reply | Email | Modify 
great by pinidiya On September 10, 2008
Good article. Nicely done.
Reply | Email | Modify 
Team Foundation Server Hosting
 © 2012  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.