1. 程式人生 > >Emit生成特定接口的類

Emit生成特定接口的類

type from 字段值 spa space ict 函數 去掉 activator

參考 動態生成類

http://www w2bc com/Article/44799

http://www.cnblogs.com/yingql/archive/2009/03/24/1420914.html

http://www.cnblogs.com/BangQ/archive/2011/07/19/2110301.html?spm=5176.100239.0.0.kAe2my

http://www.cnblogs.com/yuming1983/p/3701540.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using
System.Reflection.Emit; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public interface IGetData { void GetData(string name); } public class GetDataFromDb : IGetData { public void GetData(string name) { Console.WriteLine(
"Hello " + name); } } public class DynamicProxyBuilder { private static AssemblyBuilder DynamicAssembly; private static ModuleBuilder ModuleBuilder; private static Dictionary<string, Type> TypeList = new Dictionary<string, Type>(); public
static TTargetInterface GetProxyObject<TTargetInterface, TOriginalClass>() where TTargetInterface :class where TOriginalClass : TTargetInterface { Type target = typeof(TTargetInterface); Type baseType = typeof(TOriginalClass); CheckParams(target, baseType); Type proxyType = AutoGenerateProxyClass(target, baseType); var baseInstance = Activator.CreateInstance(baseType); return Activator.CreateInstance(proxyType, baseInstance ) as TTargetInterface; } private static Type AutoGenerateProxyClass(Type target, Type baseType) { var proxyClassName = baseType.FullName + "Proxy"; if (!TypeList.ContainsKey(proxyClassName)) { var module = GetDynamicModule(); var typeBuilder = module.DefineType(proxyClassName, System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class, typeof(System.Object), new Type[] { target }); var fieldBuilder = typeBuilder.DefineField("OriginalObj", target, System.Reflection.FieldAttributes.Public); CreateConstructorFunctionForType(baseType, typeBuilder, fieldBuilder); foreach (var methodInfo in target.GetMethods()) { CreateMethodForType(baseType, typeBuilder, methodInfo, fieldBuilder); } TypeList.Add(proxyClassName, typeBuilder.CreateType()); } return TypeList[proxyClassName]; } private static void CreateConstructorFunctionForType(Type baseType, TypeBuilder typeBuilder, FieldBuilder fieldBuilder) { var objType = typeof(object); ConstructorInfo objCtor = objType.GetConstructor(new Type[0]); ConstructorBuilder cb = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { baseType }); ILGenerator ilGenerator = cb.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); //先構建object的構造函數 ilGenerator.Emit(OpCodes.Call, objCtor); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); //將本類的構建函數的參數賦值給本類的字段 ilGenerator.Emit(OpCodes.Stfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); } private static void CreateMethodForType(Type baseType, TypeBuilder typeBuilder, MethodInfo method, FieldBuilder fieldBuilder) { var parameterInfos = method.GetParameters(); var paramTypes = new Type[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { paramTypes[i] = parameterInfos[i].ParameterType; } //準備好真正要調用的方法 var targetMethod = baseType.GetMethod(method.Name, paramTypes); //創建代理方法,使用接口中相應方法的信息,並去掉期抽象方法屬性 var methodBuilder = typeBuilder.DefineMethod(method.Name, method.Attributes & (~MethodAttributes.Abstract), method.CallingConvention , method.ReturnType, paramTypes); var il = methodBuilder.GetILGenerator(); il.EmitWriteLine("I am Proxyer"); //開始向棧中壓參數, //第1個參數 當前是this指針 il.Emit(OpCodes.Ldarg_0); //壓入當前引用的字段值 相當於 this. il.Emit(OpCodes.Ldfld, fieldBuilder); for (int i = 1; i <= parameterInfos.Length; i++) { if (i == 0) { } else if (i == 1) { il.Emit(OpCodes.Ldarg_1); } else if (i == 2) { il.Emit(OpCodes.Ldarg_2); } else if (i == 3) { il.Emit(OpCodes.Ldarg_3); } else { il.Emit(OpCodes.Ldarg_S); } } il.Emit(OpCodes.Callvirt, targetMethod); il.EmitWriteLine("I done it!Bye!!"); il.Emit(OpCodes.Ret); } private static ModuleBuilder GetDynamicModule() { if (DynamicProxyBuilder.DynamicAssembly == null) { DynamicProxyBuilder.DynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run); DynamicProxyBuilder.ModuleBuilder = DynamicProxyBuilder.DynamicAssembly.DefineDynamicModule("MainModule"); } return DynamicProxyBuilder.ModuleBuilder; } private static void CheckParams(Type targetType, Type baseType) { if (!targetType.IsInterface) throw new Exception("模板參數必須是接口"); } } public class Program { static void Main(string[] args) { var instance = DynamicProxyBuilder.GetProxyObject<IGetData, GetDataFromDb>(); instance.GetData("Aven"); Console.Read(); } } }

Emit生成特定接口的類