Introduction
Normally we are create a class at design time using the class keyword in applications. Have you ever created a class at run time? This illustration describes how to create a class at run time. For creating a class dynamically at run time, this illustration uses the following classes that satisfies the majority of the requirements.
- AssemblyName
- AssemblyBuilder
- ModuleBuilder
- TypeBuilder
- FieldBuilder
- PropertyBuilder
Let's discuss the preceding classes a little.
AssemblyName
The Assembly Name class in the System.Reflection namespace initializes a new instance of the System.Reflection.AssemblyName class with the specified display name. For more details Visit the link
Example:
- AssemblyName asemblyName;
- this.asemblyName = new AssemblyName(ClassName);
In the preceding code ClassName is a variable, that contains the class name to be created.
AssemblyBuilder
This class helps to create a dynamic assembly at run time. This is a sealed class and has no constructor. The object of this class is created using the DefineDynamicAssembly method of the AppDomain class. To learn more.
Example:
- AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(this.asemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder
This class dynamically creates a module in the project. It inherits from the Module class in System.Reflection.Emit and impliments a _ModuleBuilder interface. This class also has no constructor, hence an object of the class can be created using the DefineDynamicModule function of the assembly builder class. To learn more.
- ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
Note: MainModule is the name of the module to be created at run time.
TypeBuilder
TypeBuilder creates a new instance of the class specified by the name and inherits from System.Reflection.TypeInfo. This is also a sealed class and cannot be directly created by an object of this class. It comes from the System.Reflection.Emit namespace, the function DefineType of the ModuleBuilder class creates an object of this class.
Example:
- TypeBuilder typeBuilder = moduleBuilder.DefineType(this.asemblyName.FullName
- , TypeAttributes.Public |
- TypeAttributes.Class |
- TypeAttributes.AutoClass |
- TypeAttributes.AnsiClass |
- TypeAttributes.BeforeFieldInit |
- TypeAttributes.AutoLayout
- , null);
This class cannot be inherited and used to create a field or variable of a class. It inherits from the System.Reflection.FieldInfo class. The DefineField function of the typebilder class creates an object of this class.
Example:
- FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
Note: The DefineField function takes the three parameter names of property, datatype and access specifier.
PropertyBuilder
This class defines or creates a property of a class at runtime, it is in the System.Reflection.Emit namespace and cannot be inherited. This class inherites from the System.Reflection.PropertyInfo class. The DefineProperty function of the typebuilder class creates an object of the PropertyBuilder class.
Example:
- PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
Here in this article I have dynamically created a class using a console application and their three properties. Then displayed the information of the class in the screen.
Use the following procedure to create a class:
- Create assembly
- Create Module
- Create Instance
- Create constructor
- Create properties
Create assembly
Before creating an instance of the class you need to create or define the assembly of class as in the following:
- AssemblyName asemblyName;
- this.asemblyName = new AssemblyName(ClassName);
- AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(this.asemblyName, AssemblyBuilderAccess.Run);
In the preceding code .02 defines assembly name of class using AssemblyName class and 03 creates assembly dynamically by assemblybuilder class.
Create Module
Using the module builder class create the module of the class, as mentioned above the DefineDynamicModule function creates an object of the class. This function takes a string as module name.
- ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
As I mentioned above, the TypeBuilder class creates an instance of a class and creates an object of a TypeBuilder class using the module's DefineType function as in the following code:
- TypeBuilder typeBuilder = moduleBuilder.DefineType(this.asemblyName.FullName
- , TypeAttributes.Public |
- TypeAttributes.Class |
- TypeAttributes.AutoClass |
- TypeAttributes.AnsiClass |
- TypeAttributes.BeforeFieldInit |
- TypeAttributes.AutoLayout
- , null);
Create constructor
After creating the class, create their constructor using the DefineDefaultConstructor function typebuilder class.
- typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
Create properties
Creating a property is a little bit of a long process. To create a property of a class, we need to define the field of that property and the get and set methods, the following code creates a class's property with their get and set method.
- FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
- PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
- MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
- ILGenerator getIl = getPropMthdBldr.GetILGenerator();
- getIl.Emit(OpCodes.Ldarg_0);
- getIl.Emit(OpCodes.Ldfld, fieldBuilder);
- getIl.Emit(OpCodes.Ret);
- MethodBuilder setPropMthdBldr =typeBuilder.DefineMethod("set_" + propertyName,
- MethodAttributes.Public |
- MethodAttributes.SpecialName |
- MethodAttributes.HideBySig,
- null, new[] { propertyType });
- ILGenerator setIl = setPropMthdBldr.GetILGenerator();
- Label modifyProperty = setIl.DefineLabel();
- Label exitSet = setIl.DefineLabel();
- setIl.MarkLabel(modifyProperty);
- setIl.Emit(OpCodes.Ldarg_0);
- setIl.Emit(OpCodes.Ldarg_1);
- setIl.Emit(OpCodes.Stfld, fieldBuilder);
- setIl.Emit(OpCodes.Nop);
- setIl.MarkLabel(exitSet);
- setIl.Emit(OpCodes.Ret);
- propertyBuilder.SetGetMethod(getPropMthdBldr);
- propertyBuilder.SetSetMethod(setPropMthdBldr);
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
- using System.Threading.Tasks;
- namespace PropertyBuilderExample
- {
- public class MyClassBuilder
- {
- AssemblyName asemblyName;
- public MyClassBuilder(string ClassName)
- {
- this.asemblyName = new AssemblyName(ClassName);
- }
- public object CreateObject(string[] PropertyNames,Type[]Types)
- {
- if(PropertyNames.Length!=Types.Length)
- {
- Console.WriteLine("The number of property names should match their corresopnding types number");
- }
- TypeBuilder DynamicClass = this.CreateClass();
- this.CreateConstructor(DynamicClass);
- for(int ind=0;ind<PropertyNames.Count();ind++)
- CreateProperty(DynamicClass, PropertyNames[ind],Types[ind]);
- Type type = DynamicClass.CreateType();
- return Activator.CreateInstance(type);
- }
- private TypeBuilder CreateClass()
- {
- AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(this.asemblyName, AssemblyBuilderAccess.Run);
- ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
- TypeBuilder typeBuilder = moduleBuilder.DefineType(this.asemblyName.FullName
- , TypeAttributes.Public |
- TypeAttributes.Class |
- TypeAttributes.AutoClass |
- TypeAttributes.AnsiClass |
- TypeAttributes.BeforeFieldInit |
- TypeAttributes.AutoLayout
- , null);
- return typeBuilder;
- }
- private void CreateConstructor(TypeBuilder typeBuilder)
- {
- typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
- }
- private void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType)
- {
- FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
- PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
- MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
- ILGenerator getIl = getPropMthdBldr.GetILGenerator();
- getIl.Emit(OpCodes.Ldarg_0);
- getIl.Emit(OpCodes.Ldfld, fieldBuilder);
- getIl.Emit(OpCodes.Ret);
- MethodBuilder setPropMthdBldr =typeBuilder.DefineMethod("set_" + propertyName,
- MethodAttributes.Public |
- MethodAttributes.SpecialName |
- MethodAttributes.HideBySig,
- null, new[] { propertyType });
- ILGenerator setIl = setPropMthdBldr.GetILGenerator();
- Label modifyProperty = setIl.DefineLabel();
- Label exitSet = setIl.DefineLabel();
- setIl.MarkLabel(modifyProperty);
- setIl.Emit(OpCodes.Ldarg_0);
- setIl.Emit(OpCodes.Ldarg_1);
- setIl.Emit(OpCodes.Stfld, fieldBuilder);
- setIl.Emit(OpCodes.Nop);
- setIl.MarkLabel(exitSet);
- setIl.Emit(OpCodes.Ret);
- propertyBuilder.SetGetMethod(getPropMthdBldr);
- propertyBuilder.SetSetMethod(setPropMthdBldr);
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
- using System.Threading.Tasks;
- using PropertyBuilderExample;
- namespace PropertyBuilderExample
- {
- class Program
- {
- static void Main(string[] args)
- {
- MyClassBuilder MCB=new MyClassBuilder("Student");
- var myclass = MCB.CreateObject(new string[3] { "ID", "Name", "Address" }, new Type[3] { typeof(int), typeof(string), typeof(string) });
- Type TP = myclass.GetType();
- foreach (PropertyInfo PI in TP.GetProperties())
- {
- Console.WriteLine(PI.Name);
- }
- Console.ReadLine();
- }
- }
- }
Summery
I hope you have learned how to create a class dynamically at run time.
Sadiqabbas HiraniPosted Mar 23, 2024, 6:09 AM
Awesome Share, But, How about adding a property of List < sub dynamic class> ? Is it possible ? If so then please share some insights on it.
Ganapathi PasupathiPosted Apr 29, 2023, 3:19 PM
Sir, You make my life
Spring BootPosted Jun 3, 2021, 12:28 PM
How to create instance of this dynamic class and access its properties and assign value to them ??
Adrian SakPosted Oct 31, 2020, 10:47 AM
How to get for example Id or Name of some student?
Ameerudheen KPosted Jun 17, 2020, 5:54 AM
Why this not working in .net core? any alternate ways? getting error here ```AppDomain.CurrentDomain.DefineDynamicAssembly``` it says not such method DefineDynamicAssembly
Bert MeeusPosted Apr 3, 2020, 7:08 AM
Hi, I was able to create an instance of a dynamic class , but how do I set value to proporties?
Sunil BailwalPosted Jan 16, 2020, 3:32 PM
Nice article just need to understand one thing can we achive the same functionlity with ExpandoObject? dynamic objPolicy = new ExpandoObject(); objPolicy.Id = id; objPolicy.CreatedAt = DateTime.Now;
CompanyPosted Dec 12, 2019, 3:20 AM
Hey, Can I pass array name instead of static value when CreateObject...(means in parameters )..?
alok kumarPosted Jun 12, 2019, 4:09 AM
I want to create a dynamic class and save into folder please help
Mathews JacobPosted May 6, 2019, 2:20 AM
How to get value from this object?
Nenrikido NenrikidoPosted Dec 5, 2018, 3:15 AM
Hey, how to put inheritance in this ?
Sunil PatilPosted Sep 28, 2018, 4:26 AM
Thanks a lot for gr8 post
Mahesh NagawadePosted Aug 29, 2018, 3:39 AM
Thanks a lot for gr8 post
only workPosted Aug 16, 2018, 12:59 AM
This Code is Not working in .net core do you have solution?
Syed Azeem AliPosted Jan 23, 2018, 12:59 AM
Where is generated class located?
Stef keimanPosted Jan 25, 2017, 6:48 AM
I would like to instantiate like this: dim x as New Student
Stef keimanPosted Jan 25, 2017, 6:47 AM
That's pretty good, but I would like t instantiate like this:
Santhakumar MunuswamyPosted Apr 6, 2015, 12:33 AM
Thanks for sharing
Gowtham RajamanickamPosted Apr 5, 2015, 11:11 PM
info