首页 > 代码库 > Emit生成特定接口的类
Emit生成特定接口的类
参考 动态生成类
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生成特定接口的类
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。