Click here to Skip to main content
15,885,758 members
Articles / Programming Languages / C#

Dynamic Assemblies

Rate me:
Please Sign up or sign in to vote.
2.94/5 (10 votes)
24 Aug 2008CPOL8 min read 37.5K   636   30  
Creating Dynamic assemblies in C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

namespace DynamicAssemblyDemoWithEmit
{
    class DynamicAssemblyCreator
    {
        object bookShopRulesObj;

        public DynamicAssemblyCreator()
        {
            Assembly a = this.CreatAssembly();
            bookShopRulesObj = a.CreateInstance("BookShopRuleWithEmit.BookShopRules");
        }

        public double GetDiscount(double price , double qty)
        {
            DynamicAssemblyCreator t = new DynamicAssemblyCreator();
            Assembly a = t.CreatAssembly();

            try
            {
                if (bookShopRulesObj != null)
                {
                    bookShopRulesObj.GetType().GetField("price").SetValue(bookShopRulesObj, price);
                    bookShopRulesObj.GetType().GetField("quantity").SetValue(bookShopRulesObj, qty);

                    MethodInfo methodInfo = bookShopRulesObj.GetType().GetMethod("GetDiscount");
                    Object commission = methodInfo.Invoke(bookShopRulesObj, null);
                    if (commission is double)
                    {
                        return (Convert.ToDouble( commission) );
                    }
                }
                else
                {
                    Console.WriteLine("Error!");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error!   " + e.Message);
            }

            return 0;

        }

        /// <summary>
        /// Creating the emit dynamic dll
        /// </summary>
        /// <returns></returns>
        public Assembly CreatAssembly()
        {
            AssemblyBuilder ab = null;
            try
            {
                AssemblyName an = new AssemblyName(); // we can define asseblies unique identity
                // Version is 1.0.0.0
                an.Version = new Version(1, 0, 0, 0);
                // Set the assembly name
                an.Name = "BookShopRuleWithEmit";

                // Define a dynamic assembly
                // AssemblyBuilderAccess : Defines the access mode of the assembly use Run to avoid assembly creation.
                ab = Thread.GetDomain().DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);

                // Define a dynamic module and the filename of the assembly
                ModuleBuilder modBuilder = ab.DefineDynamicModule("BookShopRuleWithEmit", "BookShopRuleWithEmit.dll");

                // Create the public BookShopRules class (can spesify the namespace if needed)
                TypeBuilder tb = modBuilder.DefineType("BookShopRuleWithEmit.BookShopRules", TypeAttributes.Public);

                // Define two fields (both Public)
                FieldBuilder price = tb.DefineField("price", typeof(double), FieldAttributes.Public);
                FieldBuilder qty = tb.DefineField("quantity", typeof(double), FieldAttributes.Public);


                // Define GetDiscount public method, with retuen type double
                MethodBuilder adderBldr = tb.DefineMethod("GetDiscount",
                               MethodAttributes.Public, CallingConventions.Standard,
                               typeof(double),
                               new Type[0]);
                //now the implementaion of the method
                ILGenerator ilgen = adderBldr.GetILGenerator();


                Label failed = ilgen.DefineLabel();
                Label failed2 = ilgen.DefineLabel();
                Label endOfMthd = ilgen.DefineLabel();


                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, qty);
                ilgen.Emit(OpCodes.Ldarg_0);         //condition one if((price*quantity) < 100)                                   
                ilgen.Emit(OpCodes.Ldfld, price);                       //return ((price*quantity)*.025)
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Ldc_R8, 100.00);
                ilgen.Emit(OpCodes.Bgt_S, failed);

               
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, qty);
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, price);       // Body of the statement
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Ldc_R8, 0.025);
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Br_S, endOfMthd);



                ilgen.MarkLabel(failed);
                ilgen.Emit(OpCodes.Ldarg_0);            // condition two
                ilgen.Emit(OpCodes.Ldfld, qty);         // else if ((price*quantity) < 500)  
                ilgen.Emit(OpCodes.Ldarg_0);                        //return ((price*quantity)*.05)
                ilgen.Emit(OpCodes.Ldfld, price);
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Ldc_R8, 500.00);
                ilgen.Emit(OpCodes.Bgt_S, failed2);

                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, qty);
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, price);          // body of else if
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Ldc_R8, 0.05);
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Br_S, endOfMthd);


                ilgen.MarkLabel(failed2);
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, qty);
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, price);          // body of else return  ((price*quantity)*.075)
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Ldc_R8, 0.075);
                ilgen.Emit(OpCodes.Mul);
                ilgen.Emit(OpCodes.Br_S, endOfMthd);

                ilgen.MarkLabel(endOfMthd);                 // returning from the method
                ilgen.Emit(OpCodes.Ret);


                tb.CreateType();
                ab.Save("BookShopRuleWithEmit.dll");

            }
            catch (Exception e)
            {

            }

            return ab;
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Sri Lanka Sri Lanka
PhD, BSc(Eng), MCP (Web Development)

Comments and Discussions