|
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.