|
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using DynamicCodeGeneration.CustomAttributes;
using System.Threading;
namespace DynamicCodeGeneration.CodeGenerator
{
class MSILGenerator : IGenerator
{
/// <summary>
/// Default constructor
/// </summary>
public MSILGenerator()
{
}
#region IGenerator Members
/// <summary>
/// Generates assembly by directly emittint IL op-codes
/// </summary>
/// <param name="assemblyAuthorName"></param>
/// <param name="classAuthorName"></param>
/// <param name="methodAuthorName"></param>
/// <returns>Path of the generated assembly</returns>
public string GenerateAssembly(string assemblyAuthorName, string classAuthorName, string methodAuthorName)
{
AppDomain currentDomain = Thread.GetDomain();
#region Define Assembly ()
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "Derived";
AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(
assemblyName,
AssemblyBuilderAccess.Save);
Type[] constructorParameters = new Type[] { typeof(string), typeof(GenerationMode) };
ConstructorInfo constructorInfo = typeof(AssemblyLevelAttribute).GetConstructor(constructorParameters);
CustomAttributeBuilder assemblyLevelAttribute = new CustomAttributeBuilder(
constructorInfo,
new object[] { assemblyAuthorName, GenerationMode.IL });
assemblyBuilder.SetCustomAttribute(assemblyLevelAttribute);
#endregion
#region Define module (code container)
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(
"DerivedAssembly",
"DerivedAssembly.dll");
#endregion
#region Create the derived class with the entity subscription attribute
//First, we'll build a type
TypeBuilder typeBuilder = moduleBuilder.DefineType("Derived",
TypeAttributes.Public | TypeAttributes.BeforeFieldInit,
typeof(Base.Base));
//Let us apply the required attribute
constructorParameters = new Type[] { typeof(string) };
constructorInfo = typeof(ClassLevelAttribute).GetConstructor(constructorParameters);
CustomAttributeBuilder classLevelAttributeBuilder = new CustomAttributeBuilder(
constructorInfo,
new object[] { classAuthorName });
typeBuilder.SetCustomAttribute(classLevelAttributeBuilder);
#endregion
#region Constructor
//Define the default constructor (not required actually as default constructor is autmatically supplied)
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
System.Type.EmptyTypes);
ILGenerator generator = constructorBuilder.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, typeBuilder.BaseType.GetConstructor(System.Type.EmptyTypes));
generator.Emit(OpCodes.Ret);
#endregion
#region Method
// Now, let's build a method and add a custom attribute to it.
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Method",
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
null,
new Type[] { });
//Apply the event attribute to method
constructorParameters = new Type[] { typeof(ComplexityLevel), typeof(string) };
constructorInfo = typeof(MethodLevelAttribute).GetConstructor(constructorParameters);
CustomAttributeBuilder methodAttributeBuilder = new CustomAttributeBuilder(
constructorInfo,
new object[] { ComplexityLevel.SuperComplex, methodAuthorName });
methodBuilder.SetCustomAttribute(methodAttributeBuilder);
generator = methodBuilder.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, typeof(Base.Base).GetMethod("Method"));
generator.Emit(OpCodes.Ret);
#endregion
typeBuilder.CreateType(); //Close the type
assemblyBuilder.Save("Derived.dll");
return "Derived.dll";
}
/// <summary>
///
/// </summary>
public string Code
{
get
{
return string.Empty;
}
set
{
this.Code = value;
}
}
#endregion
}
}
|
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.
I work with Proteans Software Solutions. Interests include software architecture, design patterns, agile, scrum development, automated acceptance testing, books, music, travel, movies...