Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Create a Class and its Collection in Memory, Create Objects from them and Bind them to DataGrid at RunTime using CodeDOM and Reflection

0.00/5 (No votes)
17 Jul 2007 1  
Create a Class and its Collection in Memory at RunTime, then generate objects and assign values and bind to datagrid using CodeDOM and Reflection
Screenshot - DaynamicCollection.jpg

Introduction

Sometimes in programming, it happens that you want to generate code at runtime and compile it for temporary use.

This example illustrates how to create and compile code not just as an executable and run it. But it should enable you to generate and compile code in memory and use it inside your program.

This article solves some problems in database programming, for example, you store data in table as rows but actually you will represent them for the user as columns and other tables are related to it by some complex business.

This can also be used in many situations if you are familiar with Microsoft Enterprise Library Data Access Application Block.

For Microsoft Data Access Application Block, see this link.

The problems that you will face after you compile the runtime code are:

  1. How to use your class and collection?
  2. How to create objects from runtime class at runtime?
  3. How to assign and retrieve values from created objects?

You don't have a description for them (the class or the collection) - you just created them at runtime.

Background

The reader must be familiar with .NET Framework, C#, OOP.

You must also read this for better understanding:

1. CodeDOM - Dynamic Source Code Generation and Compilation

The .NET Framework includes a mechanism called the Code Document Object Model (CodeDOM) that enables developers of programs that emit source code to generate source code in multiple programming languages at run time, based on a single model that represents the code to render.

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.

See Dynamic Source Code Generation and Compilation.

2. Reflection

Reflection can also be used to create applications called type browsers, which enable users to select types and then view the information about those types.

The classes of the System.Reflection.Emit namespace provide a specialized form of reflection that enables you to build types at run time.

See Reflection Overview.

Using the Code

First, we need to include the CodeDOM:

// you will need this namespace
using System.CodeDom.Compiler;

Then you will define the CodeDOM objects that enable you to compile:

/// <summary>
/// run time compiler variables
/// </summary>
CompilerResults CompilationResult;

CodeDomProvider RuntimeCompiler = new Microsoft.CSharp.CSharpCodeProvider();

CompilerParameters Parameters = new CompilerParameters();

You need to configure your runtime compiler to tell it, for example, to compile in memory:

/// <summary>
/// This configuration tells the runtime compiler
/// to generate code in Memory
///</summary>

Parameters.GenerateExecutable = false;

Parameters.GenerateInMemory = true;

Parameters.IncludeDebugInformation = false;

1. How to Compile a Runtime Generated Code

Note: Here txtsourcecode.text represents the actual string that represents a valid C# code:

// compile the code and return the result in compilerresult 
CompilationResult = RuntimeCompiler.CompileAssemblyFromSource
				(Parameters, txtSourcecode.Text);

2. How to Create an Instance from the Class and Collection

Note: See the full source code demo - it is commented very well.

//object that represents our class
object myClass;
//Create instance from our collection
object myClasslist = CompilationResult.CompiledAssembly.CreateInstance
					("DynamicCollection.EntityList");
//create objects equal to the number you entered
for (int i = 0; i < Convert.ToInt32(txtNoObjects.Text); i++)
{
//Create Object instance from the class
myClass = CompilationResult.CompiledAssembly.CreateInstance("DynamicCollection.Entity");

3. How to make your Code Discover your Class using Reflection

//Get Properties of our class at run time using reflection
System.Reflection.PropertyInfo[] ProI= myClass.GetType().GetProperties();

4. Assign Values for Each Property in your Objects

//for each property, set a value
//for simplicity, I make all things strings
//this is because finally you can convert string to anything 
foreach (System.Reflection.PropertyInfo Pro in ProI)
{
//set member variable value
Pro.SetValue(myClass, "Smile" + i, null);
}

5. Add Objects to the Collection using Reflection and Invoke

// we do this because the Invoke method take the values 
//array of objects
object[] myObject = new object[1];
myObject[0] = myClass;
//Add the Object to our collection using reflection and Invoke
myClasslist.GetType().GetMethod("Add").Invoke(myClasslist, myObject);

6. Bind your Collection to the Data Grid

//bind our collection to the datagrid
//what a smart datagrid we have? thanks to datagrid team
dataGridView1.DataSource = myClasslist;

Points of Interest

I wonder how something like this can be solved in C++ (outside the .NET Framework) and what the difficulty level will be.

History

  • 18-7-2007: First release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here